# Google Maps EU Scraper - B2B Leads, No API Key (`harvestlab/google-maps-eu-scraper`) Actor

Find EU businesses by keyword and city using OpenStreetMap/Nominatim - no Google API key needed. Name, address, phone, website, coordinates. Auto proxy routing NL/BE/DE/FR/SE. AI enrichment (5 LLM providers). $0.005/place PPE.

- **URL**: https://apify.com/harvestlab/google-maps-eu-scraper.md
- **Developed by:** [Nick](https://apify.com/harvestlab) (community)
- **Categories:** Lead generation, Business, MCP servers
- **Stats:** 1 total users, 0 monthly users, 0.0% runs succeeded, NaN bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per usage

This Actor is paid per platform usage. The Actor is free to use, and you only pay for the Apify platform usage, which gets cheaper the higher subscription plan you have.

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

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp.md).

If your project is in a different language, use the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).


# README

## Google Maps EU Scraper - Find European Businesses by Keyword and City

> **Part of the harvestlab MCP suite** - 36 RAG-ready, AI-agent-payment-ready Apify actors covering ecommerce, social, travel, news, jobs, EU B2B, dev-tools, and government data. [See the full suite](https://apify.com/harvestlab)

Find European businesses by keyword and city - without a Google API key. Scrape names, addresses, phones, websites, GPS coordinates, and category from OpenStreetMap. Ideal for B2B lead generation across NL, BE, DE, FR, SE, and the UK. Pay only $0.005 per place with no monthly minimum.

---

### Why This Actor

Most Places scrapers require a Google Maps Platform API key, come with monthly minimums, or charge $2-7 per 1,000 requests. This actor uses **OpenStreetMap via the Overpass API** and **Nominatim geocoding** - both free, open, and ODbL-licensed. There is nothing to configure before your first run beyond a search keyword and a city name.

EU coverage is a first-class feature. The actor automatically routes Apify proxy traffic through the correct country exit (NL for Amsterdam, DE for Berlin, FR for Paris, SE for Stockholm, GB for London) to maximise Nominatim and Overpass response reliability. For Dutch or Belgian B2B workflows, it pairs directly with kvk-scraper and contact-extractor to build a complete "discover - verify - enrich - contact" pipeline.

---

### Key Features

| Feature | Detail |
|---------|--------|
| **Data source** | OpenStreetMap via Overpass API + Nominatim geocoding |
| **No API key required** | Free, open data - zero billing setup |
| **EU proxy auto-routing** | Injects `apifyProxyCountry` (NL/BE/DE/FR/SE/GB) based on target location |
| **Rich EU coverage** | All OSM-mapped businesses across 30+ European cities |
| **Output fields** | name, category, address, city, country, postalCode, phone, website, lat/lng, OSM ID/type, raw tags |
| **AI business enrichment** | 5 LLM providers: OpenRouter, Anthropic, Google AI, OpenAI, Ollama |
| **AI output fields** | sector, target_market, business_size, key_insights[], lead_score (1-10), summary |
| **Pay-per-event pricing** | $0.005/place, $0.005/AI analysis - pay only for what you get |
| **Input aliases** | Accepts `query`/`location`/`maxItems` for CLI/API callers |
| **Google Maps links** | Each result includes a ready-to-click Google Maps search URL |
| **Deduplication** | OSM ID-based dedup prevents double-charging for duplicates |
| **Polite crawling** | 1-second delays between Overpass requests; Nominatim fair-use compliant |

---

### Competitor Comparison

| Scraper | Price | API Key Needed | EU Proxy Routing | AI Enrichment |
|---------|-------|---------------|-----------------|---------------|
| **Google Maps EU Scraper (this)** | **$0.005/place** | **No** | **Auto (6 countries)** | **Yes (5 providers)** |
| compass/crawler-google-places (374k users) | ~$0.002-0.004/place | Yes (Google Maps Platform) | Manual | No |
| Outscraper | $0.003-$0.01/row | Yes (Google) | Manual | Limited |
| PhantomBuster Google Maps | From $69/mo | Yes (Google) | No | No |
| DataForSEO Places API | $0.0015+/call | Yes | No | No |
| Google Maps Platform (direct) | $2-$17/1,000 calls | Yes | N/A | No |

**Key differentiator**: No Google API key, EU-native proxy routing, and optional AI lead scoring in a single pay-per-event actor. compass/crawler-google-places leads the category with 374,787 users and Google-sourced data (richer reviews and ratings) - if you need Google Maps reviews and ratings, use that actor. If you need EU B2B leads without API setup and want AI enrichment, this actor is the faster path.

---

### Use Cases

#### 1. B2B prospecting for EU SMBs
A sales team targeting independent accountants in the Netherlands runs `"accountant"` in `"Amsterdam"` with a 15 km radius and 500 max results. They get name, phone, website, and coordinates for every OSM-mapped accountancy firm. They pipe the `website` URLs into contact-extractor to pull managing partner emails, then cross-reference against kvk-scraper for SBI code and headcount before outreach.

#### 2. Restaurant finder app
A travel app needs a JSON feed of all restaurants within 3 km of city centres across five European capitals. One run per city exports name, category, GPS coordinates, phone, and website in a format ready for GeoJSON rendering on a map tile layer.

#### 3. Property nearby amenities
A proptech platform wants to show buyers what amenities (schools, pharmacies, supermarkets, gyms) are within 1 km of any listing. This actor provides that data from OSM without requiring a per-query Google Maps API call.

#### 4. Travel guide content
A travel content agency generates city-by-city guides. They run `"museum"` or `"hotel"` searches per destination and feed the AI enrichment to get a 2-3 sentence summary and sector classification for each venue - ready to paste into CMS templates.

#### 5. Retail site selection
A franchise operator researching expansion runs `"coffee shop"` or `"gym"` searches in target districts to map existing competitor density, informing their site selection model with real location data.

#### 6. Competitor location mapping
A logistics company wants to know where all competing courier depots are in the Benelux region. They run `"courier"` and `"logistics"` searches across Brussels, Antwerp, Rotterdam, and Amsterdam and export the results to a shared spreadsheet.

#### 7. Field sales routing
A medical device sales rep needs a list of all GP clinics and specialist practices in their territory. They run `"doctor"` and `"clinic"` searches for their region and export name, address, and phone for route planning in Google Maps.

#### 8. Local SEO audit
An agency running local SEO for clients checks OSM listing completeness for their client's category (e.g., `"physiotherapy"` in `"Cologne"`) to identify gaps in business directory coverage and opportunities for citations.

---

### EU B2B Pipeline

This actor is the **discovery layer** in the harvestlab EU B2B pipeline:

````

google-maps-eu-scraper    (discover businesses by keyword + city)
|
v
contact-extractor         (extract emails, LinkedIn, 175+ tech stack signals from each website)
|
v
kvk-scraper               (cross-reference NL businesses: legal form, SBI code, director names)
|
v
eu-b2b-leadgen            (orchestrate KvK + KBO + Handelsregister + SIRENE + VIES VAT validation)
|
v
Your CRM / n8n / Make     (HubSpot contact creation, Slack alert, Google Sheet row)

````

**Dutch B2B example**: Run `google-maps-eu-scraper` for `"IT consultancy"` in `"Amsterdam"`, then feed each `website` into `contact-extractor` for CTO/founder emails, then verify each company via `kvk-scraper` for legal status and employee count before sequencing outreach.

**Belgian B2B example**: Run for `"notaris"` in `"Ghent"`, feed into `contact-extractor`, cross-reference with `belgium-kbo-scraper` for VAT number and NACE code.

---

### Input Parameters

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `searchQuery` | string | required | Business type or name (e.g., `restaurant`, `plumber`, `Starbucks`). |
| `searchLocation` | string | `Amsterdam` | City, region, or address (e.g., `Berlin Mitte`, `Paris 75001`). |
| `searchRadius` | integer | `5000` | Search radius in metres around the location (100-50000). |
| `maxResults` | integer | `50` | Maximum number of places to return (1-1000). |
| `proxyConfiguration` | object | Apify proxy | Proxy settings. Datacenter proxy is sufficient. |
| `enableAiAnalysis` | boolean | `false` | Enable LLM-generated business profile per place. |
| `llmProvider` | string | `openrouter` | AI provider: `openrouter`, `anthropic`, `google`, `openai`, `ollama`. |
| `llmModel` | string | provider default | Override the model name (e.g., `gpt-4o`, `claude-opus-4-5`). |
| `openrouterApiKey` | string | - | OpenRouter API key (or set `OPENROUTER_API_KEY` env var). |
| `anthropicApiKey` | string | - | Anthropic API key (or set `ANTHROPIC_API_KEY` env var). |
| `googleApiKey` | string | - | Google AI API key (or set `GOOGLE_API_KEY` env var). |
| `openaiApiKey` | string | - | OpenAI API key (or set `OPENAI_API_KEY` env var). |
| `ollamaBaseUrl` | string | `http://localhost:11434` | Ollama server URL for self-hosted models. |

**CLI aliases** (hidden schema fields): `query` maps to `searchQuery`, `location` maps to `searchLocation`, `maxItems` maps to `maxResults`.

**LLM provider defaults**: OpenRouter uses `google/gemini-2.0-flash-001` (cheapest), Anthropic uses `claude-sonnet-4-20250514`, Google AI uses `gemini-2.0-flash`, OpenAI uses `gpt-4o-mini`, Ollama uses `llama3.1`.

---

### Output Schema

Each item in the dataset represents one business place:

```json
{
  "url": "https://www.google.com/maps/search/Cafe%20de%20Jaren%2C%20Nieuwe%20Doelenstraat%2C%20Amsterdam",
  "name": "Cafe de Jaren",
  "category": "restaurant",
  "address": "Nieuwe Doelenstraat 20, Amsterdam, NL",
  "city": "Amsterdam",
  "country": "NL",
  "postalCode": "1012 CP",
  "phone": "+31 20 625 5771",
  "website": "https://www.dejaren.nl",
  "latitude": 52.3693,
  "longitude": 4.8990,
  "osmId": 123456789,
  "osmType": "node",
  "tags": {
    "amenity": "restaurant",
    "name": "Cafe de Jaren",
    "addr:street": "Nieuwe Doelenstraat",
    "addr:housenumber": "20",
    "addr:city": "Amsterdam",
    "addr:country": "NL",
    "addr:postcode": "1012 CP",
    "phone": "+31 20 625 5771",
    "website": "https://www.dejaren.nl",
    "cuisine": "international",
    "outdoor_seating": "yes"
  },
  "aiAnalysis": {
    "sector": "Food & Beverage",
    "target_market": "B2C - tourists, students, and Amsterdam residents seeking a grand cafe experience",
    "business_size": "small",
    "key_insights": [
      "Canal-side location with premium pricing potential",
      "Outdoor seating drives summer foot traffic",
      "International cuisine broadens customer base"
    ],
    "lead_score": 4,
    "summary": "Cafe de Jaren is a well-known Amsterdam grand cafe with riverside terrace seating and an international menu. Strong local brand recognition makes it a mid-range B2C prospect; low lead score for B2B outreach but high value for hospitality supplier targeting."
  },
  "scraped_at": "2026-04-28T10:30:00+00:00"
}
````

**Note**: `phone`, `website`, `postalCode`, and `aiAnalysis` may be empty or null. OSM tag completeness varies by region and place type. City centres and major business districts typically have better coverage.

***

### Data Completeness by Region

OSM tag completeness varies across Europe. Approximate coverage for key B2B fields:

| Region | Name | Address | Phone | Website |
|--------|------|---------|-------|---------|
| Netherlands | ~98% | ~85% | ~45% | ~40% |
| Germany | ~97% | ~82% | ~40% | ~35% |
| France | ~96% | ~78% | ~35% | ~30% |
| Belgium | ~95% | ~80% | ~40% | ~35% |
| Sweden | ~95% | ~75% | ~35% | ~30% |
| UK | ~94% | ~72% | ~30% | ~28% |

City centres and business districts have significantly higher completeness than rural areas. The AI enrichment (`enableAiAnalysis`) supplements missing metadata by inferring sector and target market from available tags.

***

### Technical Details

- **Data source**: [OpenStreetMap](https://www.openstreetmap.org/) via the [Overpass API](https://overpass-api.de/) and [Nominatim geocoding](https://nominatim.openstreetmap.org/).
- **Search strategy**: Queries match on OSM `name` tag (regex, case-insensitive) AND on category tags (`amenity`, `shop`, `leisure`, `office`, `tourism`). Searching `"restaurant"` returns both places named "Restaurant X" and places tagged `amenity=restaurant`.
- **Proxy routing**: The actor automatically sets `apifyProxyCountry` to the appropriate country code (NL/BE/DE/FR/SE/GB) based on the detected location, improving response times and reducing timeouts.
- **Google Maps URL**: The `url` field contains a Google Maps search link constructed from the place name and address. It is a convenience link - not a scraped Google Maps URL.
- **OSM ID stability**: OSM element IDs are stable within a major version but can change during OSM data corrections. Use `name + address` as the stable business identifier across runs.
- **Rate limiting**: Nominatim enforces 1 request/second. Overpass is rate-limited by query complexity. The actor includes polite 1-second delays and retries on HTTP 429.
- **Deduplication**: OSM ID-based deduplication runs before charging, so duplicate elements returned by Overpass are never pushed to the dataset or billed.

***

### Integrations

| Actor | What It Adds |
|-------|-------------|
| **[kvk-scraper](https://apify.com/harvestlab/kvk-scraper)** | Dutch KvK registration: legal form, SBI code, director names, headcount. Cross-reference OSM businesses with the Dutch Chamber of Commerce. |
| **[contact-extractor](https://apify.com/harvestlab/contact-extractor)** | From a website URL, extract email addresses, LinkedIn profiles, job titles, and 175+ tech stack signals. Build a full contact record for each lead. |
| **[eu-b2b-leadgen](https://apify.com/harvestlab/eu-b2b-leadgen)** | Orchestrate KvK + KBO + Handelsregister + SIRENE in one run with VIES VAT validation and email enrichment. |
| **[review-analyzer](https://apify.com/harvestlab/ai-review-analyzer)** | Analyse Google/Trustpilot reviews for any business found by this actor - understand sentiment and competitive positioning. |
| **[news-monitor](https://apify.com/harvestlab/news-monitor)** | Track press coverage for any company name discovered via this actor. |

***

### Scheduling and Automation

Schedule monthly runs in Apify Console to keep EU B2B prospect lists fresh for a target city and keyword. Connect a `webhookUrl` in n8n or Make to push each extracted business directly into a CRM, Google Sheet, or Slack channel as soon as the run completes.

Example automation: "IT consultancy Amsterdam" - monthly EU Maps run - n8n webhook - HubSpot contact creation.

***

### Pricing

| Event | Price | When It Fires |
|-------|-------|--------------|
| `place-scraped` | $0.005 | Each business place extracted from OpenStreetMap |
| `ai-analysis-completed` | $0.005 | Per place when AI lead scoring and profile runs |

At 1,000 places that is $5 - cheaper than a single LinkedIn Sales Navigator contact export row.

***

### Legal and Compliance

#### OpenStreetMap Data License

OpenStreetMap data is licensed under the [Open Database License (ODbL) v1.0](https://opendatacommons.org/licenses/odbl/). You are free to copy, distribute, transmit, and adapt the data, even for commercial purposes, provided you:

1. **Attribute** OpenStreetMap and its contributors in any product or work derived from the data.
2. **Share-Alike**: If you alter or build upon the data, you must distribute the result under the same ODbL license.
3. Keep any produced works (e.g., databases) open if they incorporate OSM data.

Required attribution: "© OpenStreetMap contributors" with a link to `https://www.openstreetmap.org/copyright`.

#### Nominatim and Overpass API Usage Policy

This actor uses the public Nominatim API (hosted by the OSM Foundation) and the public Overpass API (hosted by overpass-api.de). Both have fair-use policies:

- **Nominatim**: Maximum 1 request per second; must identify the application via `User-Agent` (handled automatically).
- **Overpass API**: Requests should be reasonable in scope; complex queries may be throttled during peak hours.

For high-volume production use (10,000+ requests/day), consider a self-hosted [Nominatim Docker image](https://github.com/mediagis/nominatim-docker) or a commercial Nominatim provider.

#### Scraping and ToS Compliance

This actor **does not scrape Google Maps, Google Search, or any Google properties**. It uses free, open-source OpenStreetMap data via public APIs. No Google Maps Platform API keys are used or required. All data is ODbL-licensed.

**User responsibilities**:

- Ensure your use of extracted business data complies with applicable data protection laws in your jurisdiction, including GDPR (EU), UK GDPR, and national implementations.
- Business contact data (phone numbers, emails) extracted from websites via contact-extractor is subject to GDPR lawful basis requirements for marketing use.
- Do not use this data to build unsolicited marketing lists without a lawful basis under GDPR Article 6.
- You are solely responsible for how you use, store, and process the data extracted by this actor.

#### GDPR Notice

Business addresses, phone numbers, and websites of sole traders or micro-businesses may constitute personal data under GDPR. If you operate in the EU or process data about EU residents, ensure you have a lawful basis for your data processing activities. The actor itself does not store any personal data beyond the current run's dataset.

***

### About

Built by [Nick Lukianenko](https://apify.com/nick.lukianenko) as part of the EU B2B Lead Generation actor portfolio. For support or feature requests, open a GitHub issue or contact via the Apify Actor page.

# Actor input Schema

## `searchQuery` (type: `string`):

Business type or name to search for (e.g., 'restaurant', 'plumber', 'Starbucks')

## `searchLocation` (type: `string`):

City, region, or address to search near (e.g., 'Amsterdam', 'Berlin Mitte', 'Paris 75001')

## `searchRadius` (type: `integer`):

Radius around the location to search (metres). Default 5000 = 5km.

## `maxResults` (type: `integer`):

Maximum number of places to return (1-1000).

## `proxyConfiguration` (type: `object`):

Apify proxy settings. Datacenter proxy is sufficient for Nominatim/Overpass.

## `enableAiAnalysis` (type: `boolean`):

Generate an AI business profile (sector, target market, key insights, lead score) for each place.

## `llmProvider` (type: `string`):

AI provider for business profile enrichment.

## `llmModel` (type: `string`):

Specific model name (leave blank to use provider default: OpenRouter=google/gemini-2.0-flash-001, Anthropic=claude-sonnet-4-20250514, Google=gemini-2.0-flash, OpenAI=gpt-4o-mini, Ollama=llama3.1).

## `openrouterApiKey` (type: `string`):

OpenRouter API key for AI enrichment. Get one at https://openrouter.ai/keys

## `anthropicApiKey` (type: `string`):

Anthropic API key. Get one at https://console.anthropic.com/settings/keys

## `googleApiKey` (type: `string`):

Google AI API key. Get one at https://aistudio.google.com/app/apikey

## `openaiApiKey` (type: `string`):

OpenAI API key. Get one at https://platform.openai.com/api-keys

## `ollamaBaseUrl` (type: `string`):

Base URL of your Ollama server (self-hosted models only).

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

Alias for searchQuery.

## `location` (type: `string`):

Alias for searchLocation.

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

Alias for maxResults.

## Actor input object example

```json
{
  "searchLocation": "Amsterdam",
  "searchRadius": 5000,
  "maxResults": 50,
  "proxyConfiguration": {
    "useApifyProxy": true
  },
  "enableAiAnalysis": false,
  "llmProvider": "openrouter",
  "ollamaBaseUrl": "http://localhost:11434"
}
```

# 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 = {
    "searchLocation": "Amsterdam",
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("harvestlab/google-maps-eu-scraper").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 = {
    "searchLocation": "Amsterdam",
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("harvestlab/google-maps-eu-scraper").call(run_input=run_input)

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

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

```

## CLI example

```bash
echo '{
  "searchLocation": "Amsterdam",
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call harvestlab/google-maps-eu-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=harvestlab/google-maps-eu-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Google Maps EU Scraper - B2B Leads, No API Key",
        "description": "Find EU businesses by keyword and city using OpenStreetMap/Nominatim - no Google API key needed. Name, address, phone, website, coordinates. Auto proxy routing NL/BE/DE/FR/SE. AI enrichment (5 LLM providers). $0.005/place PPE.",
        "version": "0.1",
        "x-build-id": "oSHrxdDuZhIddVfCV"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/harvestlab~google-maps-eu-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-harvestlab-google-maps-eu-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/harvestlab~google-maps-eu-scraper/runs": {
            "post": {
                "operationId": "runs-sync-harvestlab-google-maps-eu-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/harvestlab~google-maps-eu-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-harvestlab-google-maps-eu-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "required": [
                    "searchQuery",
                    "searchLocation"
                ],
                "properties": {
                    "searchQuery": {
                        "title": "Search Query",
                        "type": "string",
                        "description": "Business type or name to search for (e.g., 'restaurant', 'plumber', 'Starbucks')"
                    },
                    "searchLocation": {
                        "title": "Location",
                        "type": "string",
                        "description": "City, region, or address to search near (e.g., 'Amsterdam', 'Berlin Mitte', 'Paris 75001')"
                    },
                    "searchRadius": {
                        "title": "Search Radius (metres)",
                        "minimum": 100,
                        "maximum": 50000,
                        "type": "integer",
                        "description": "Radius around the location to search (metres). Default 5000 = 5km.",
                        "default": 5000
                    },
                    "maxResults": {
                        "title": "Max Results",
                        "minimum": 1,
                        "maximum": 1000,
                        "type": "integer",
                        "description": "Maximum number of places to return (1-1000).",
                        "default": 50
                    },
                    "proxyConfiguration": {
                        "title": "Proxy Configuration",
                        "type": "object",
                        "description": "Apify proxy settings. Datacenter proxy is sufficient for Nominatim/Overpass."
                    },
                    "enableAiAnalysis": {
                        "title": "Enable AI Enrichment",
                        "type": "boolean",
                        "description": "Generate an AI business profile (sector, target market, key insights, lead score) for each place.",
                        "default": false
                    },
                    "llmProvider": {
                        "title": "LLM Provider",
                        "enum": [
                            "openrouter",
                            "anthropic",
                            "google",
                            "openai",
                            "ollama"
                        ],
                        "type": "string",
                        "description": "AI provider for business profile enrichment.",
                        "default": "openrouter"
                    },
                    "llmModel": {
                        "title": "LLM Model",
                        "type": "string",
                        "description": "Specific model name (leave blank to use provider default: OpenRouter=google/gemini-2.0-flash-001, Anthropic=claude-sonnet-4-20250514, Google=gemini-2.0-flash, OpenAI=gpt-4o-mini, Ollama=llama3.1)."
                    },
                    "openrouterApiKey": {
                        "title": "OpenRouter API Key",
                        "type": "string",
                        "description": "OpenRouter API key for AI enrichment. Get one at https://openrouter.ai/keys"
                    },
                    "anthropicApiKey": {
                        "title": "Anthropic API Key",
                        "type": "string",
                        "description": "Anthropic API key. Get one at https://console.anthropic.com/settings/keys"
                    },
                    "googleApiKey": {
                        "title": "Google AI API Key",
                        "type": "string",
                        "description": "Google AI API key. Get one at https://aistudio.google.com/app/apikey"
                    },
                    "openaiApiKey": {
                        "title": "OpenAI API Key",
                        "type": "string",
                        "description": "OpenAI API key. Get one at https://platform.openai.com/api-keys"
                    },
                    "ollamaBaseUrl": {
                        "title": "Ollama Base URL",
                        "type": "string",
                        "description": "Base URL of your Ollama server (self-hosted models only).",
                        "default": "http://localhost:11434"
                    },
                    "query": {
                        "title": "Query (alias)",
                        "type": "string",
                        "description": "Alias for searchQuery."
                    },
                    "location": {
                        "title": "Location (alias)",
                        "type": "string",
                        "description": "Alias for searchLocation."
                    },
                    "maxItems": {
                        "title": "Max Items (alias)",
                        "type": "integer",
                        "description": "Alias for maxResults."
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
