# Company Finder: B2B Lists by City and Industry (`kondasviktor/google-maps-company-finder`) Actor

Find companies by industry in any city worldwide. Websites, phones, ratings, shortlist scores. Adaptive map tiles, GeoNames city lookup (no Nominatim). Optional BYOK AI. Registry financials in a later release.

- **URL**: https://apify.com/kondasviktor/google-maps-company-finder.md
- **Developed by:** [Viktor Kondas](https://apify.com/kondasviktor) (community)
- **Categories:** Lead generation, Automation, AI
- **Stats:** 1 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.50 / 1,000 supplier record saveds

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

## Company Finder: B2B Lists by City and Industry

Find companies of a type in **any city worldwide** — phone, website, ratings, coordinates, and transparent readiness scoring.

**Store slug:** [`kondasviktor/google-maps-company-finder`](https://apify.com/kondasviktor/google-maps-company-finder)

**Worked examples (preview mode):**

| City | Industry | Typical cost |
| --- | --- | --- |
| Oslo | logistics | ~$0.10–0.15 for 10–40 candidates |
| Austin | software agencies | ~$0.10–0.20 for 20 candidates |
| Budapest | dental clinics | ~$0.10 for a 5–10 place Store QA run |

Schedule a weekly run with the same city + industry when you only want **new** companies (monitoring fields land in a later release). You pay per saved place, minimum **$0.10/run**.

City coordinates use the [GeoNames](https://www.geonames.org/) `cities15000` dump (CC BY 4.0). Custom GeoJSON still overrides the lookup. Public Nominatim is **not** used.

### What it does

- Discovers companies on Google Maps by **city + industry preset** (or free-text search terms) in **any country**.
- Adaptive map tiles with a hard `maxCandidates` cost cap (worst-case charge printed in the log before scrolling).
- Returns structured JSON/CSV/Excel with phone, website, `companyKey`, ratings, coordinates, and shortlist fields.
- **Procurement mode** adds transparent supplier readiness scoring, risk flags, and shortlist status.
- Optional **multi-provider AI scoring** (BYOK): Gemini, Claude, ChatGPT, or OpenRouter. Included Gemini for paid plans arrives with the company-suite Release 2 events.
- Optional **Google Sheets** export (service account).
- Built for **n8n**, **Make**, **Zapier**, and vibe-coder agent workflows.

**Optional enrichment:** pipe result `website` URLs into the sibling **Website Intelligence + Contact Extractor** actor for emails, tech stack, and EU compliance flags. Then verify legal names / VAT with **Company Data Verifier**.

### Who it's for

1. **Procurement teams** building first-pass supplier shortlists for clinics, catering, cleaning, security, maintenance, facilities, and local IT services.
2. **Sales teams** building contactable SME lead lists by city or district.
3. **Vibe coders** powering AI company-discovery agents.
4. **Market researchers** auditing service density in any city.
5. **Agencies** running competitor mapping for clients.

### What this score is — and is not

This actor helps you **discover and rank public Google Maps evidence**. It does **not** verify legal entity status, insurance, certifications, financial health, pricing, or formal vendor approval.

Use the output for:

- company / supplier discovery
- shortlist preparation
- outreach prioritization

Do **not** use it as the sole basis for contract award or formal vendor qualification.

### What data you get

| Field | Description |
|-------|-------------|
| `companyKey` | Registrable website domain, or `placeId` when there is no site |
| `placeId` | Stable Google Maps place identifier |
| `title` | Business name |
| `categoryName` | Primary category |
| `address`, `city`, `postalCode` | Parsed location |
| `phone`, `website`, `websiteDomain` | Contact channels |
| `locations` | Branch addresses rolled up by domain |
| `totalScore`, `reviewsCount` | Rating signals |
| `matchedSearchTerms` | Search terms that surfaced this company |
| `discoveredBy` | Which term + map tile found it |
| `supplierReadinessScore` | 0–100 shortlist readiness score |
| `shortlistStatus` | `READY`, `REVIEW`, `LOW_EVIDENCE`, `EXCLUDE` |
| `scoreConfidence` | `HIGH`, `MEDIUM`, `LOW` |
| `shortlistReasons` | Human-readable reasons |
| `riskFlags` | Missing contact, weak evidence, category mismatch, etc. |
| `shortlistReady` | True when status is `READY` |
| `contactableLead` | Leads mode only — has phone/website and rating ≥ 3.5 |
| `aiScore`, `aiSummary` | When AI scoring enabled |
| `reviews[]` | When `includeReviews` is true |

Legacy aliases `procurementScore` and `vendorTier` remain for backward compatibility.

### How to use it

1. **Configure input** — search terms (or industry preset), city/country, language, limits.
2. **Run** on Apify cloud (recommended) or locally with `apify run`.
3. **Download** dataset as JSON, CSV, or Excel from the run page.

### Input presets

#### Budapest dental clinics

```json
{
  "searchTerms": ["fogászat", "dental"],
  "location": "Budapest, Hungary",
  "countryCode": "HU",
  "language": "hu",
  "maxResultsPerSearch": 5,
  "outputMode": "procurement"
}
```

Store input **prefill** uses this small cap so Apify automated QA finishes within 5 minutes. For real shortlists, raise `maxResultsPerSearch` (e.g. 50–100) and/or add terms like `fogorvos`.

Published Store examples (5, small caps for fast QA):

- [Oslo logistics](https://apify.com/kondasviktor/google-maps-company-finder/examples/oslo-logistics-company-finder-preview)
- [Austin software agencies](https://apify.com/kondasviktor/google-maps-company-finder/examples/austin-software-agencies-company-finder)
- [Manchester logistics](https://apify.com/kondasviktor/google-maps-company-finder/examples/manchester-logistics-company-finder)
- [Budapest dental clinics](https://apify.com/kondasviktor/google-maps-company-finder/examples/budapest-dental-clinics-company-finder)
- [Warsaw HVAC](https://apify.com/kondasviktor/google-maps-company-finder/examples/warsaw-hvac-company-finder)

#### Budapest cleaning suppliers

```json
{
  "searchTerms": ["takarítás", "cleaning service", "facility management"],
  "location": "Budapest, Hungary",
  "countryCode": "HU",
  "language": "hu",
  "maxResultsPerSearch": 100,
  "minRating": 3.5,
  "outputMode": "procurement"
}
```

#### Warsaw IT vendors

```json
{
  "searchTerms": ["software house", "IT services", "outsourcing IT"],
  "location": "Warsaw, Poland",
  "countryCode": "PL",
  "language": "pl",
  "maxResultsPerSearch": 50,
  "outputMode": "leads"
}
```

#### Oslo logistics (GeoNames + industry preset)

```json
{
  "mode": "preview",
  "country": "NO",
  "city": "Oslo",
  "industryPreset": "logistics",
  "maxCandidates": 15,
  "language": "en",
  "outputMode": "procurement"
}
```

### Language and localization

Works worldwide. Pass local keywords and set `language` / `countryCode` for Maps UI and geocoding:

| Feature | Support |
|---------|---------|
| **Search terms in any language** | Yes — e.g. `"fogászat"`, `"klimatyzacja"`, `"logistik"` |
| **Maps UI language (`language`)** | Yes — sets `?hl=` on search URLs |
| **City lookup** | GeoNames `cities15000` (not Nominatim) |
| **Category/relevance scoring** | Accent-normalized matching against your `searchTerms` |

Combining local + English terms often finds more listings because Google Maps indexes both.

### Optional AI scoring (BYOK)

| Provider | Input field | Key source |
| --- | --- | --- |
| **Gemini** (default in auto) | `geminiApiKey` | Actor env `GEMINI_API_KEY` or BYOK |
| **Claude** | `anthropicApiKey` | [Anthropic Console](https://console.anthropic.com/) |
| **ChatGPT** | `openaiApiKey` | [OpenAI API keys](https://platform.openai.com/api-keys) |
| **OpenRouter** | `openrouterApiKey` | [OpenRouter](https://openrouter.ai/keys) |
| **auto** | First available key above | Tries Gemini → Claude → OpenAI → OpenRouter |

### Google Sheets integration

1. Create a Google Cloud service account with Sheets API access.
2. Set `GOOGLE_SERVICE_ACCOUNT_KEY` in actor environment (JSON string).
3. Share the target spreadsheet with the service account email (Editor).
4. Enable `enableGoogleSheetsExport` and pass `googleSheetsUrl`.

### Use with Claude, Cursor, and MCP

This Actor is available on the [Apify MCP server](https://mcp.apify.com). Ask for a company shortlist by city and industry (Oslo logistics, Austin agencies, Budapest dental, …). Keep `maxCandidates` / `maxResultsPerSearch` small for a smoke. Schedule daily if you refresh a city list; you pay per saved place, minimum **$0.10/run**.

### FAQ

**Is scraping Google Maps legal?**\
You are responsible for compliance with Google’s Terms of Service and local laws. This actor collects publicly visible listing data for legitimate business research.

**How is this different from generic Google Maps scrapers?**\
Focused on **city + industry company shortlists** with transparent readiness scoring, risk flags, matched search terms, and optional BYOK evidence summaries — not raw record dumps.

**How many results can I get per run?**\
Up to **500 per search term** (`maxResultsPerSearch`). Use `maxCandidates` for a hard cost cap. Duplicates are removed by `placeId`.

**What is AI scoring and does it cost extra on Apify?**\
AI scoring is optional. BYOK uses your LLM key (`company-profile-byok` when enabled in monetization). Included Gemini for paying Apify users ships with the scheduled company-suite events. Scraping works with zero LLM keys.

**How much does it cost?**\
Pay-per-event: **$2.50 per 1,000 company/place records** (`place`), minimum **$0.10** per run. From **23 Oct 2026**: optional AI profile and financials events + explicit min charge top-up. Platform usage is not passed to users (PPE only).

**How do I scrape Google Maps companies in any city?**\
Set `city` + `country` (or `location` + `countryCode`), an `industryPreset` or `searchTerms`, and start with `maxCandidates: 10` for a smoke test.

### Local development

```bash
cd google-maps-cee-scraper
npm install
npm run build
npm test
apify run --input-file=INPUT.test.json
npx playwright install chromium
```

### Pricing

Pay-per-event: **$2.50 per 1,000 company/place records** (`place` event), minimum charge **$0.10** per run.

Use **pay per event only** in Apify Console (do not pass platform usage to users). Keep `apify-actor-start`. Do not enable `apify-default-dataset-item`.

Scheduled from **23 Oct 2026**: `company-profile`, `company-profile-byok`, `financials-found`, `run-minimum`.

### Suite path

**Finder → Profiler → Verifier.** Discover companies here, enrich websites with [Company Profiler](https://apify.com/kondasviktor/website-intelligence-contact-extractor), then clean VAT/registry fields with [Company Data Verifier](https://apify.com/kondasviktor/company-data-verifier).

#### Weekly schedule (recurring)

Save a task with fixed `city` + `industryPreset` and `maxCandidates: 50`. Schedule weekly. Event cost ≈ `$2.50 × places / 1000`, minimum **$0.10/run**. Example: 40 new places/week ≈ **$0.40/month** of `place` events (plus min charge if a week is empty).

### Related

- [Company Profiler](https://apify.com/kondasviktor/website-intelligence-contact-extractor) — Emails, tech stack, EU signals, optional Gemini profile
- [Company Data Verifier](https://apify.com/kondasviktor/company-data-verifier) — VAT (VIES) and no-key registry cleanup
- [Dealer / Distributor Locator](https://apify.com/kondasviktor/dealer-distributor-locator) — Expand a known brand locator instead of Maps search
- [PDF Procurement Document Extractor](https://apify.com/kondasviktor/pdf-procurement-document-extractor) — Certs / reports from supplier sites
- [Website Change Monitor](https://apify.com/kondasviktor/website-change-monitor) — Watch shortlisted pages

[All Actors](https://apify.com/kondasviktor)

### Feedback

Open an issue on the actor’s Apify page or contact [Vibe Coder's Life](https://vibecoderslife.com/#contact).

# Changelog

This Actor's version history is a separate document: https://apify.com/kondasviktor/google-maps-company-finder/changelog.md

# Actor input Schema

## `mode` (type: `string`):

preview = Maps discovery only. profile = discovery + AI company profiles (included Gemini for paid plans / BYOK). full = profile + no-key registry financials (NO/FR/US-SEC). Example: preview.

## `country` (type: `string`):

ISO 3166-1 alpha-2 country code for any country (e.g. NO, US, HU, GB). Alias of countryCode.

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

Legacy alias for country. Kept so existing tasks and schedules keep working. Example: HU.

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

City name, e.g. Oslo, Austin TX, Budapest. Takes priority over location when both are set.

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

Legacy city/region string (e.g. Budapest, Hungary). Used when city is empty.

## `industryPreset` (type: `string`):

Expands to local-language + English Maps search terms. Example: logistics.

## `searchTerms` (type: `array`):

Extra keywords in any language, added on top of the industry preset. Example: cold chain, 3PL.

## `languages` (type: `array`):

Languages for preset term expansion. Defaults to English plus the country language. Example: en, no.

## `language` (type: `string`):

Google Maps UI language (en, hu, no, …). Example: en.

## `radiusKm` (type: `number`):

Optional override. When empty, radius is sized from city population (about 3–30 km). Example: 15.

## `maxCandidates` (type: `integer`):

Hard cap on unique companies discovered. Worst-case cost is printed in the log before scrolling. Prefill stays low for Store QA. Example: 20.

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

Final rows pushed to the dataset after filters (≤ maxCandidates). Example: 50.

## `maxResultsPerSearch` (type: `integer`):

Maximum places to collect per search term per map tile (max 500). Example: 50.

## `gridMode` (type: `string`):

auto = adaptive tiles over the city; off = single map centre; dense = start with a finer grid. Example: auto.

## `maxCells` (type: `integer`):

Cap on adaptive tiles. Tiling also stops when a round adds under 5% new companies. Example: 64.

## `includeReviews` (type: `boolean`):

Extract review snippets for stronger shortlist evidence and optional BYOK AI summaries.

## `maxReviewsPerPlace` (type: `integer`):

Cap reviews when includeReviews is enabled.

## `minRating` (type: `number`):

Filter out places below this star rating.

## `minReviewCount` (type: `integer`):

Filter out places with fewer reviews.

## `enableAIScoring` (type: `boolean`):

Optional BYOK enrichment: evidence-based supplier summary per place. Requires your LLM API key below. Included Gemini for paid plans arrives in Release 2.

## `aiProvider` (type: `string`):

LLM provider for AI scoring. Use auto to pick the first available key (Gemini → Claude → OpenAI → OpenRouter).

## `aiModel` (type: `string`):

OpenRouter model slug when aiProvider is openrouter or auto (OpenRouter leg).

## `geminiApiKey` (type: `string`):

Google AI Studio key for AI scoring when aiProvider is gemini or auto.

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

Claude API key when aiProvider is claude or auto.

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

ChatGPT API key when aiProvider is openai or auto.

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

OpenRouter key when aiProvider is openrouter or auto.

## `enableGoogleSheetsExport` (type: `boolean`):

Append results to a spreadsheet (requires GOOGLE_SERVICE_ACCOUNT_KEY).

## `googleSheetsUrl` (type: `string`):

Spreadsheet URL when export is enabled.

## `outputMode` (type: `string`):

standard = raw fields; procurement = supplier shortlist scoring; leads = contactable lead flag only.

## `customGeolocation` (type: `object`):

Optional Point, Polygon, or MultiPolygon. Overrides city lookup (GeoNames / Maps viewport). Example: {"type":"Point","coordinates":\[10.75,59.91],"radiusMeters":15000}.

## Actor input object example

```json
{
  "mode": "preview",
  "country": "NO",
  "city": "Oslo",
  "industryPreset": "logistics",
  "language": "en",
  "maxCandidates": 10,
  "maxResults": 100,
  "maxResultsPerSearch": 10,
  "gridMode": "auto",
  "maxCells": 64,
  "includeReviews": false,
  "maxReviewsPerPlace": 10,
  "minRating": 0,
  "minReviewCount": 0,
  "enableAIScoring": false,
  "aiProvider": "auto",
  "enableGoogleSheetsExport": false,
  "outputMode": "procurement"
}
```

# Actor output Schema

## `suppliers` (type: `string`):

Deduplicated Google Maps company records with optional procurement shortlist scoring.

## `runOverview` (type: `string`):

Open the run in Apify Console to inspect logs, Live View, and billing.

# 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 = {
    "mode": "preview",
    "country": "NO",
    "city": "Oslo",
    "industryPreset": "logistics",
    "language": "en",
    "maxCandidates": 10,
    "maxResultsPerSearch": 10,
    "aiProvider": "auto",
    "outputMode": "procurement"
};

// Run the Actor and wait for it to finish
const run = await client.actor("kondasviktor/google-maps-company-finder").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 = {
    "mode": "preview",
    "country": "NO",
    "city": "Oslo",
    "industryPreset": "logistics",
    "language": "en",
    "maxCandidates": 10,
    "maxResultsPerSearch": 10,
    "aiProvider": "auto",
    "outputMode": "procurement",
}

# Run the Actor and wait for it to finish
run = client.actor("kondasviktor/google-maps-company-finder").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 '{
  "mode": "preview",
  "country": "NO",
  "city": "Oslo",
  "industryPreset": "logistics",
  "language": "en",
  "maxCandidates": 10,
  "maxResultsPerSearch": 10,
  "aiProvider": "auto",
  "outputMode": "procurement"
}' |
apify call kondasviktor/google-maps-company-finder --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,kondasviktor/google-maps-company-finder"
        }
    }
}
```

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/O6sKYnTUEjgj555Cc/builds/Bj0PtY3z74b8w0Lti/openapi.json
