# Google Maps New Business Monitor — Fresh Local Leads (`paulovitor18/google-maps-new-business-monitor`) Actor

Be the first to reach every business that opens in a Google Maps search. Watch a search and each run returns only the businesses that newly appeared, with phone, website and email pulled from the site. Pay per new lead, not per rescan.

- **URL**: https://apify.com/paulovitor18/google-maps-new-business-monitor.md
- **Developed by:** [MoreLock](https://apify.com/paulovitor18) (community)
- **Categories:** Lead generation, Automation, Business
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per event

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/platform/actors/running/actors-in-store#pay-per-event

## 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/docs.md):

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

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python/docs.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/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 New Business Monitor — Fresh Local Leads

Be the first to reach every business that opens near you. This new business monitor watches a Google Maps search and hands you, on every run, **only the fresh local leads** — the businesses that just started showing up — already carrying phone, website, and email pulled from the site. It is a continuous local business monitor that runs on its own: a stream of fresh leads where you never rescan the whole area, you get only the difference.

Works globally, on any Google Maps search in any city. For businesses in Brazil it adds a bonus layer: the CNPJ and public registry data (legal name, status, size) when the site publishes it.

### Overview

You pick what to watch and where ("coffee shops" in "Austin, TX") and schedule the run. The first time, the monitor records the current inventory of that search (the baseline). On the following runs it compares what is on Google Maps now against what was there before and delivers **only the delta**: the businesses that appeared (new businesses), the ones that vanished (possible closure), and the ones that changed name or category.

For each **new business** — and only for it — the monitor opens the listing and does the heavy lifting: phone, official website, email, social links, full address with postal code and GPS. When the business is in Brazil and its site publishes a CNPJ in text, the number is validated by check digits and the public registry is queried (legal name, registration status, size, capital, activity, partners) in the same record. The baseline and the already-seen businesses come out in the light format; the expensive enrichment is reserved for what is new.

This is a purpose-built monitor, not a generic scraper with a filter bolted on. The parsing understands Google Maps cards, the website crawl looks for real contact details, and the delta engine is the same audited core that powers the one-shot **Google Maps Local Leads** scraper. This Actor trades the one-time sweep for continuous watching.

### Features

- **Delta between runs:** each run reports only what changed — new businesses, possible closures, and edits — never the whole list again.
- **Isolated state per watch:** search term + location define the watch; every combination keeps its own history, so two monitors never contaminate each other.
- **Enrichment only on the new:** phone, website, email, social links (and CNPJ/registry for Brazil) are fetched only for freshly detected businesses, so cost tracks the delta, not the size of the search.
- **Match and chain guard:** a CNPJ is "high confidence" only when the legal name matches the business name; a CNPJ repeated across several units in the same delta is flagged as a chain and charged **only once**.
- **Honest degradation:** if Google Maps is down or blocked, the monitor **preserves the state** and charges nothing, so a block is never mistaken for "everyone closed".
- **Schedulable:** built to run hourly or daily via Apify Schedules; the first run is the baseline, the rest are the alert.

### Input example

```json
{
  "search_term": "coffee shops",
  "location": "Austin, TX",
  "max_results": 60,
  "enrich_from_website": true,
  "max_new_hydrated": 40,
  "proxy": { "useApifyProxy": true }
}
````

### Output example

A **new business** record detected in the delta (with website contact enrichment):

```json
{
  "change_type": "new_business",
  "search_term": "coffee shops",
  "location": "Austin, TX",
  "name": "Cedar & Bean",
  "category": "Coffee shop",
  "address": "812 W 5th St, Austin, TX 78703",
  "postal_code": "78703",
  "region": "TX",
  "phone": "(512) 320-1200",
  "phone_digits": "5123201200",
  "website": "https://www.cedarandbean.com/",
  "email": "hello@cedarandbean.com",
  "rating": 4.8,
  "reviews_count": 42,
  "place_url": "https://www.google.com/maps/place/Cedar+%26+Bean/...",
  "registry_enriched": false,
  "match_confidence": null,
  "detected_at": "2026-07-18T09:00:00.000Z"
}
```

On the **first run** of a watch, each business comes out as `change_type: "baseline"` in the light format (name, category, rating, location) — the snapshot of what already exists. A business that vanished comes out as `change_type: "possible_closure"`, but **only after it has been missing from 3 consecutive runs** — Google Maps returns a rotating sample of the results, so a single absence means nothing and is never reported. For a Brazilian business whose site publishes a CNPJ, the same `new_business` record also carries `cnpj`, `legal_name`, `registration_status`, and `registry_enriched: true`.

**You are never charged twice for the same business.** Once a business has been reported (as new, or as a possible closure), the monitor keeps it in its memory forever. If a place that was flagged as a possible closure shows up again later, it is recorded as a reopening — a free signal — and never billed again as a new lead.

### Parameters

| Field | Type | Default | Description |
|---|---|---|---|
| `search_term` | string | `"restaurants"` | What to watch, exactly as you would type it into Maps. |
| `location` | string | `"Austin, TX"` | City and area to watch. Search term + location define the watch. |
| `max_results` | integer | `120` | Safety cap of businesses watched (the monitor scrolls to the end of the list; ~120 is the practical Maps maximum). Changing the cap re-baselines the watch. |
| `enrich_from_website` | boolean | `true` | For each new business: visits the site (when it exists) for email, social links, and (for Brazil) CNPJ, then queries the registry. |
| `max_new_hydrated` | integer | `25` | Cap of new businesses hydrated and enriched per run (protects the first delta run after a large search; the excess is deferred to the next run). Max 40. |
| `stateStoreName` | string | `""` (auto) | Advanced. Empty = state derived from search term + location. Fill in only to control the watch explicitly. |
| `mode` | select | `auto` | `auto` = baseline on the 1st run, delta after. `baseline` = force a rebase of the current state. |
| `proxy` | object | Apify Proxy | Rotating datacenter by default; switch to Residential + a nearby country if you see blocking at volume. |

### Tips

- **Schedule it, do not run it by hand.** The value is the recurrence: set up a Schedule (daily or hourly). The 1st run becomes the baseline automatically; the following ones only alert you to what is new.
- **One watch per search term + location.** To watch "coffee shops" and "gyms" in the same city, create two schedules; each keeps its own state, without mixing.
- **Narrower searches give sharper alerts.** "burger joints" + "Brooklyn, NY" produces a much more actionable "a competitor opened" signal than "restaurants" + "New York".
- **The baseline is free of per-business charges.** The first run only charges the run itself (not per business); it is the initial snapshot. Money starts when a real new business shows up.
- **Check `match_confidence`:** `low` means the CNPJ from the site may belong to a group/chain entity, not the exact unit on the map (Brazilian businesses only).

### Use cases

- **B2B lead generation / fresh new business leads:** be the first to reach every restaurant, clinic, or gym that opens near you, with phone and website contact already in hand.
- **Newly opened businesses / new entrants:** know the moment a new business opens in your segment and neighborhood, ahead of the competition — a live feed of newly opened businesses in your area.
- **Competitor tracking (competitive intelligence):** monitor competitors in a segment and an area to know instantly when a new competitor appears (or disappears) on the map.
- **Continuous B2B prospecting for agencies:** deliver clients a weekly stream of qualified local leads instead of a static list that ages.
- **Franchise / retail expansion:** track the density of a segment in a market over time to decide where to enter.
- **Incremental CRM enrichment:** only the new records come in, already carrying contact details.
- **Closure signal:** `possible_closure` flags places that dropped off the map for 3 runs in a row, useful for cleaning a book of business or mapping churn in a sector.

### FAQ

**What exactly changes between the 1st run and the following ones?** The 1st run of a watch (search term + location) is the **baseline**: it records what already exists, in the light format, and charges only the run. From the 2nd run on, the monitor compares against the previous state and delivers the **delta** — new businesses (enriched), possible closures, and changes.

**Does it work for tracking new business openings?** Yes, that is exactly the use case: on each run it lists only the new businesses that started showing up in that Maps search, with contact details.

**Does it work outside Brazil?** Yes. New business detection and website contact enrichment (email, phone, social links) work on any Google Maps search worldwide. The CNPJ / registry layer is a bonus that only applies to Brazilian businesses; elsewhere those fields simply stay empty and you are not charged for them.

**How does the monitor keep its state?** In a named store, derived from search term + location, that persists between runs. Each watch is isolated, so watching two terms or two cities never blinds one to the other.

**Does every new business come with contact details?** Not always, and the Actor is honest about it. Email and CNPJ only appear when the business has a website and the site publishes the data in scrapable text. Without that, the field stays empty and you do not pay for enrichment that did not happen.

**What is `match_confidence: "low"`?** It is the warning that a CNPJ found may not belong to that exact unit: either the legal name does not match the business name, or it is a **chain** (the same CNPJ showed up across several units in the delta, one shared corporate site). The data is labeled, and the chain is charged **only once**.

**If Google Maps is down, does the monitor wipe everything?** No. A blocked run **preserves the state** and charges nothing; it emits a `STATUS: UNAVAILABLE` record. A block is never read as "every business closed" (the cardinal sin of a monitor).

**What if the search has more results than the cap?** The monitor scrolls toward the end of the list. If it does not reach the real end — because the search overflows the cap, or because scrolling ran out of time budget — `possible_closure` records are **not computed** on that run (marked `window_truncated` in the summary), because a business that fell past the cutoff did not necessarily close. New businesses within the window keep being detected. For the sharpest closure signal, narrow the search term + location until the search fits comfortably inside the cap.

**Why 3 runs before reporting a closure?** Because Google Maps does not return a stable list. The same search, minutes apart, gives back a rotating sample of a larger set — measured on a live search: 49, then 39, then 50 businesses, with nothing having opened or closed. A monitor that trusted a single absence would cry wolf on healthy businesses and re-detect them as "new" when they rotate back. Requiring 3 consecutive absences, plus permanent memory of every business ever seen, is what makes the closure signal meaningful and the billing exactly-once.

**A run ended before enriching every new business. Did I lose them?** No. Each run works within a time budget; whatever it cannot open and enrich in time is left for the next run, **not emitted and not charged** (shown as `deferred` in the summary). You never pay for a partial record, and nothing is dropped.

**A search that is legitimately empty?** A real search with no businesses is a valid state, not an error: the monitor computes the delta normally over that state.

**Why do I need a proxy?** The default (Apify Proxy datacenter) is tested and works on Google Maps without captcha. At high volume, if a cookie consent or block appears, switch to Residential and a country near your target area in the proxy selector.

### Pricing

Pay per result (PPE): you pay for the run and for the novelty, not for the rescan.

| Event | When it is charged |
|---|---|
| `monitor_run` | Once per valid run (renders the search and computes the delta). A blocked run or a source that is down is **not charged**. |
| `new_business` | Each business that started appearing since the previous run, already hydrated (phone/website/postal code). An already-seen business is **not re-charged**; the 1st run (baseline) does **not** charge per business. |
| `registry_enriched` | Only when a real CNPJ is found on a new business's site and resolved in the registry. Charged **once per unique CNPJ** — a chain with N units on the same CNPJ does not multiply. |

**You do NOT pay for:** the baseline list (only the run), already-seen businesses, a blocked/down search, our own errors, or enrichment that did not happen (site without CNPJ / no site = honest abstention).

### Related Actors

- [**Google Maps Local Leads with Email, Phone & CNPJ**](https://apify.com/paulovitor18/gmaps-brasil-leads) — the one-shot sweep (same engine, without the delta): the complete list of businesses in a search.
- [**Monitor de Nuevos Negocios en Google Maps (ES)**](https://apify.com/paulovitor18/google-maps-monitor-nuevos-negocios) — the Spanish-native twin of this monitor (LatAm / Spain).
- [**Monitor de Novos Negócios no Google Maps (BR, +CNPJ)**](https://apify.com/paulovitor18/gmaps-brasil-monitor) — the Brazilian twin, with the CNPJ registry layer.
- [**CNPJ Bulk Lookup**](https://apify.com/paulovitor18/cnpj-bulk-lookup) — Brazilian registry data for a list of CNPJs.

### Changelog

- 0.1.10: closure signal now requires **3 consecutive absences** (Google Maps returns a rotating sample, so one absence is not a closure), and every business ever seen is **kept in memory** — a place that reappears after being flagged is recorded as a reopening and **never billed again as a new lead**. Both the list scroll and the enrichment now run under a **time budget**: a run always delivers what it managed to collect instead of ending empty, and the rest rolls over to the next run uncharged. Default cap of businesses enriched per run adjusted to 5.
- 0.1: first version — monitor of new businesses in a Google Maps search, with delta between runs (new / closure / change), isolated state per watch, website contact enrichment on the new ones (plus CNPJ/registry for Brazil), chain guard, and honest degradation.

### Contact

Questions, issues, or requests for a new source: use the Actor's Issues tab.

# Actor input Schema

## `search_term` (type: `string`):

What to watch on Google Maps, exactly as you would type it (e.g. "coffee shops", "dental clinics", "gyms"). The monitor stores the set of businesses for this search and, on each run, reports only the ones that newly appeared.

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

City and area to watch (e.g. "Austin, TX", "London", "São Paulo, SP"). Search term + location together define the watch: changing either one creates a separate monitor with isolated state.

## `max_results` (type: `integer`):

The monitor scrolls the search to the END of the list; this is a safety cap (Google Maps usually lists up to ~120 per search). The delta is 100% reliable when the cap covers the whole list (the normal case). If the search is so broad that it overflows the cap, 'possible closures' are not computed on that run (flagged in the summary) so no false alarm is raised — in that case, narrow the search term + location. Changing the cap re-baselines the watch (the watched window changed).

## `enrich_from_website` (type: `boolean`):

For each NEW business detected, visits the website (once) looking for email, social links and — when the site publishes a Brazilian CNPJ in text — validates it and queries the public registry (legal name, status, size, capital, activity, partners). It is best-effort: if a contact or CNPJ is not found the field comes back empty and you are NOT charged for the enrichment.

## `max_new_hydrated` (type: `integer`):

Limits how many NEW businesses get their detail page opened and enriched on each run (cost control). The monitor's cost is proportional to the DELTA — in steady state only a few new businesses show up per day. The cap protects the first delta run after a large search. Anything above the cap is NOT lost and NOT charged: it is picked up on the next run. Opening and enriching one business takes ~30s, so raising this raises the run time proportionally.

## `stateStoreName` (type: `string`):

Leave empty to let the monitor derive a stable name from search term + location (each watch is isolated automatically). Fill in only if you want to explicitly control which state this run reads/writes (e.g. share one watch across schedules).

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

auto = the first run becomes the baseline and following runs report the delta. baseline = force a re-baseline (rebase the current state, without charging for new businesses) — use it to reset the watch history.

## `proxy` (type: `object`):

Network routing. The default (Apify Proxy, rotating datacenter) was measured returning 200 on Google Maps without captcha. If you see blocking/consent at volume, select Residential and a country close to your target area.

## `self_test` (type: `boolean`):

Do not use in production. Ignores the search and runs the engine's known-answers battery (frozen-feed parse, empty search, website enrichment, honest abstention) to prove the parser and egress are still correct.

## Actor input object example

```json
{
  "search_term": "coffee shops",
  "location": "Austin, TX",
  "max_results": 120,
  "enrich_from_website": true,
  "max_new_hydrated": 5,
  "stateStoreName": "",
  "mode": "auto",
  "proxy": {
    "useApifyProxy": true
  },
  "self_test": false
}
```

# Actor output Schema

## `delta` (type: `string`):

Records computed on this run (baseline on the 1st; new businesses / closures / changes on the following ones), in the format described in dataset\_schema.json.

## `summary` (type: `string`):

Run counters: mode (baseline/delta), new businesses, closures, changes, enriched, and the intended/effective 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 = {
    "proxy": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("paulovitor18/google-maps-new-business-monitor").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 = { "proxy": { "useApifyProxy": True } }

# Run the Actor and wait for it to finish
run = client.actor("paulovitor18/google-maps-new-business-monitor").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 '{
  "proxy": {
    "useApifyProxy": true
  }
}' |
apify call paulovitor18/google-maps-new-business-monitor --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Google Maps New Business Monitor — Fresh Local Leads",
        "description": "Be the first to reach every business that opens in a Google Maps search. Watch a search and each run returns only the businesses that newly appeared, with phone, website and email pulled from the site. Pay per new lead, not per rescan.",
        "version": "0.1",
        "x-build-id": "TJ6MMhFCyLmiW8HWJ"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/paulovitor18~google-maps-new-business-monitor/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-paulovitor18-google-maps-new-business-monitor",
                "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/paulovitor18~google-maps-new-business-monitor/runs": {
            "post": {
                "operationId": "runs-sync-paulovitor18-google-maps-new-business-monitor",
                "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/paulovitor18~google-maps-new-business-monitor/run-sync": {
            "post": {
                "operationId": "run-sync-paulovitor18-google-maps-new-business-monitor",
                "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",
                "properties": {
                    "search_term": {
                        "title": "Search term",
                        "type": "string",
                        "description": "What to watch on Google Maps, exactly as you would type it (e.g. \"coffee shops\", \"dental clinics\", \"gyms\"). The monitor stores the set of businesses for this search and, on each run, reports only the ones that newly appeared.",
                        "default": "restaurants"
                    },
                    "location": {
                        "title": "City / area",
                        "type": "string",
                        "description": "City and area to watch (e.g. \"Austin, TX\", \"London\", \"São Paulo, SP\"). Search term + location together define the watch: changing either one creates a separate monitor with isolated state.",
                        "default": "Austin, TX"
                    },
                    "max_results": {
                        "title": "Cap of businesses watched",
                        "minimum": 1,
                        "maximum": 120,
                        "type": "integer",
                        "description": "The monitor scrolls the search to the END of the list; this is a safety cap (Google Maps usually lists up to ~120 per search). The delta is 100% reliable when the cap covers the whole list (the normal case). If the search is so broad that it overflows the cap, 'possible closures' are not computed on that run (flagged in the summary) so no false alarm is raised — in that case, narrow the search term + location. Changing the cap re-baselines the watch (the watched window changed).",
                        "default": 120
                    },
                    "enrich_from_website": {
                        "title": "Enrich new businesses from their website (email/phone, + CNPJ for Brazilian businesses)",
                        "type": "boolean",
                        "description": "For each NEW business detected, visits the website (once) looking for email, social links and — when the site publishes a Brazilian CNPJ in text — validates it and queries the public registry (legal name, status, size, capital, activity, partners). It is best-effort: if a contact or CNPJ is not found the field comes back empty and you are NOT charged for the enrichment.",
                        "default": true
                    },
                    "max_new_hydrated": {
                        "title": "Cap of new businesses hydrated per run",
                        "minimum": 0,
                        "maximum": 40,
                        "type": "integer",
                        "description": "Limits how many NEW businesses get their detail page opened and enriched on each run (cost control). The monitor's cost is proportional to the DELTA — in steady state only a few new businesses show up per day. The cap protects the first delta run after a large search. Anything above the cap is NOT lost and NOT charged: it is picked up on the next run. Opening and enriching one business takes ~30s, so raising this raises the run time proportionally.",
                        "default": 5
                    },
                    "stateStoreName": {
                        "title": "State store name (advanced)",
                        "type": "string",
                        "description": "Leave empty to let the monitor derive a stable name from search term + location (each watch is isolated automatically). Fill in only if you want to explicitly control which state this run reads/writes (e.g. share one watch across schedules).",
                        "default": ""
                    },
                    "mode": {
                        "title": "Mode",
                        "enum": [
                            "auto",
                            "baseline"
                        ],
                        "type": "string",
                        "description": "auto = the first run becomes the baseline and following runs report the delta. baseline = force a re-baseline (rebase the current state, without charging for new businesses) — use it to reset the watch history.",
                        "default": "auto"
                    },
                    "proxy": {
                        "title": "Proxy",
                        "type": "object",
                        "description": "Network routing. The default (Apify Proxy, rotating datacenter) was measured returning 200 on Google Maps without captcha. If you see blocking/consent at volume, select Residential and a country close to your target area.",
                        "default": {
                            "useApifyProxy": true
                        }
                    },
                    "self_test": {
                        "title": "Diagnostic mode (fixture-pack regression)",
                        "type": "boolean",
                        "description": "Do not use in production. Ignores the search and runs the engine's known-answers battery (frozen-feed parse, empty search, website enrichment, honest abstention) to prove the parser and egress are still correct.",
                        "default": false
                    }
                }
            },
            "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
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
