# Google Maps Lead Qualifier | Website Gaps + Outreach (`lirafrt/local-business-funnel-gap-finder`) Actor

Turn Google Maps results or existing business lists into qualified sales opportunities. Audit public websites, detect booking and lead-generation gaps, rank leads by confidence, recommend services, and generate evidence-backed outreach.

- **URL**: https://apify.com/lirafrt/local-business-funnel-gap-finder.md
- **Developed by:** [Murilo Lira](https://apify.com/lirafrt) (community)
- **Categories:** Marketing, Business, SEO tools
- **Stats:** 2 total users, 0 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $4.00 / 1,000 qualified opportunities

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.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

### Find local businesses you can pitch today

Enter a niche and US city. Get contactable local businesses with verified booking or lead-capture gaps, the service to pitch, and a tailored first message. **Sales-ready leads and high-quality near misses are delivered separately.**

This Actor combines Google Maps discovery, public website auditing, contact-route extraction, commercial qualification, and channel-specific outreach. It is built for agencies and freelancers selling online booking, lead capture, websites, tracking, or CRM automation to local businesses.

#### What you receive

| Result | Included information |
|---|---|
| Business | Name, category, address, rating, reviews, website, and Google Maps URL |
| Best contact route | Public email, phone, checked contact form, or public WhatsApp URL, with source provenance |
| Verified opportunity | Opportunity score, lead tier, top gaps, supporting evidence, and recommended service |
| Ready outreach | Email subject/body, call opener, form message, or WhatsApp message for the available channel |
| Quality controls | Evidence confidence, profile completeness, audit completeness, missing fields, and qualification explanation |

The default view puts the sales decision first:

```text
Business -> lead tier -> best contact -> opportunity -> top gaps
         -> service to sell -> first message -> website -> Google Maps
````

### Run your first Google Maps lead search

1. Leave **Input mode** set to Google Maps search.
2. Enter a niche, city, and state, such as `auto repair shops in Tampa FL`.
3. Choose how many businesses to inspect and run the Actor.

```json
{
  "inputMode": "maps_search",
  "searchQueries": ["auto repair shops in Tampa FL"],
  "maxResultsPerQuery": 20,
  "maxTotalResults": 20,
  "maxDiscoveryCostUsd": "0.50",
  "targetService": "auto",
  "minimumOpportunityScore": 40,
  "nearMissMinimumOpportunityScore": 25,
  "minimumConfidenceScore": 0.90,
  "minimumInformationCompletenessScore": 0.85,
  "includeNearMisses": true,
  "generatePitchAngle": true,
  "outputLanguage": "en"
}
```

Good starting searches for the US-first offer include:

- `auto repair shops in Tampa FL`;
- `roofing contractors in Charlotte NC`;
- `beauty salons in Phoenix AZ`.

### What makes a lead sales-ready

A row reaches the default **Sales-ready leads** dataset only when every required gate passes:

```text
opportunity score >= 40
evidence confidence >= 90%
business profile completeness >= 85%
website audit completeness >= max(87%, configured profile floor)
commercial output completeness = 100%
overall applicable information completeness >= 87%
usable public contact route is required
critical identity and provenance fields are valid
audit status is success, partial, or trusted no_website
```

The sales-ready score cutoff is fixed at 40. This keeps qualification and per-result charging deterministic; input changes cannot relabel a standard sales-ready score as research output without the qualified event.

The 85% profile and 90% evidence values are minimums and may be raised. The audit gate is always at least 87% and rises with a stricter configured profile floor. The profile minimum allows one optional field to be absent when six of seven profile fields are valid: `6 / 7 = 85.71%`. That subscore is exposed separately as `weakestGroupCompletenessScore`; the buyer-facing `informationCompletenessScore` is the actual known/applicable total and has its own hard 87% gate.

Critical requirements cannot be compensated by percentages. A sales-ready lead needs:

- a credible business identity;
- a valid website or trusted Google Maps no-website claim;
- a usable email, phone, checked contact form, or public WhatsApp URL;
- evidence supporting at least one commercial gap;
- a matching service recommendation;
- complete channel-specific outreach.

`false` and numeric `0` are known information. `null`, blank strings, placeholders, malformed URLs, and unusable phone numbers are not.

### Near misses

Near misses are useful leads that pass the same evidence, information, audit, provenance, contactability, and commercial-output gates but score below the sales-ready threshold.

With the defaults, a near miss has an opportunity score from **25 through 39**. It is written to the separate **Near misses** dataset with:

- `nearMissReason`;
- `opportunityPointsNeeded`;
- the best contact route;
- top verified gaps;
- the matching service and outreach fields.

Near misses do not trigger the `qualified-opportunity` event. Records below the quality gates are not disguised as near misses; they appear only in optional audit evidence and aggregate run diagnostics.

### Contact extraction and outreach

The Actor searches checked public pages for:

- `mailto:` email addresses and visible email text;
- the Google Maps source phone;
- same-host contact pages with a usable form;
- public WhatsApp contact links.

The preferred route is selected in this order: usable public email, valid phone, checked contact form, then WhatsApp. The output records both the selected value and its source.

Important email terminology:

- `domain_matched` means the public email domain matches the business website;
- `public_free_provider` means the public email uses a common mailbox provider;
- `public_syntax_valid` means the public address is syntactically usable;
- none of these labels claims inbox ownership or guaranteed deliverability.

Generated outreach is evidence-specific and channel-specific. The Actor does not send messages automatically; review the evidence and copy before contacting a business.

### Output datasets

#### Sales-ready leads

The default dataset contains only contactable, fully qualified opportunities. Qualified publication and the `qualified-opportunity` charge occur atomically.

Important fields include:

```text
businessName
leadTier
bestContactChannel
bestContactValue
bestContactSourceType
bestContactSourceUrl
bestEmail
phone
contactFormUrl
whatsappUrl
opportunityScore
topVerifiedGaps
serviceToSell
emailSubject
emailBody
callOpener
contactFormMessage
whatsappMessage
website
mapsUrl
```

#### Near misses

When `includeNearMisses` is true, high-quality records below the opportunity threshold are published to the run-scoped `near_misses` dataset. They never enter the default export.

#### Audit evidence

Set `outputMode` to `all_audits` to publish every audit outcome to the separate `audit_results` dataset. This mode is for research and troubleshooting; it does not change membership in Sales-ready leads or Near misses.

Rows that are neither qualified nor valid near misses keep technical diagnostics, scores, detector states, website, and Maps provenance, but `salesPackageRedacted` is true and usable contact values, discovered secondary-page URLs, raw crawl errors, booking URLs, service recommendations, top gaps, and outreach copy are removed. This prevents stricter or disabled gates from turning the audit dataset into an uncharged sales export.

Dataset views control columns and their order. They do not filter rows. Physical dataset separation provides the output guarantee.

The legacy `output.results` link and `qualified-opportunities` view remain available for existing integrations; new clients should use `qualifiedLeads` and the `sales-ready` view.

#### Run summary

The `RUN_SUMMARY` key-value-store record reconciles:

- discovered, normalized, unique, and duplicate records;
- audited, qualified, near-miss, filtered, pushed, and charged records;
- rejected or unsafe inputs and their reasons;
- worker or publication failures;
- spending-limit termination;
- child Maps Actor ID, run ID, dataset ID, status, cost ceiling, and reported cost;
- all active thresholds, qualification rate, and opportunity-score statistics;
- an explicit zero-qualified reason and suggested next actions.

### Pricing

The current primary event costs **$0.004 per sales-ready qualified opportunity**:

| Qualified leads | Qualified-opportunity events |
|---:|---:|
| 100 | $0.40 |
| 1,000 | $4.00 |

Near misses do not trigger that event, and zero qualified leads means zero `qualified-opportunity` events. The small Apify Actor-start event and the compute/discovery work still exist, so near misses do not add a qualified-opportunity event charge, but the run is not cost-free.

Google Maps discovery runs through a child Actor with an explicit `maxDiscoveryCostUsd` ceiling. The reported child cost is included in `RUN_SUMMARY` so the run can be reconciled.

### Input modes

Exactly one source mode is accepted. Unknown top-level fields and conflicting sources are rejected.

#### Google Maps search

The default provider is `compass/crawler-google-places`. Discovery has hard item, cost, memory, and timeout limits, and its dataset is streamed into the audit pipeline.

#### Existing Apify dataset

```json
{
  "inputMode": "dataset",
  "apifyDatasetId": "YOUR_DATASET_ID",
  "maxTotalResults": 100,
  "websiteField": "website",
  "nameField": "title"
}
```

Recognized fallbacks include `website`, `websiteUrl`, `website_url`, `title`, `name`, `businessName`, `rating`, `totalScore`, `reviewsCount`, and `reviewCount`.

#### Business objects

```json
{
  "inputMode": "businesses",
  "businesses": [
    {
      "title": "Relax and Smile Dental Care",
      "website": "https://www.relaxandsmile.com/",
      "category": "Dentist",
      "rating": 4.9,
      "reviewsCount": 500
    }
  ]
}
```

#### Domains

```json
{
  "inputMode": "domains",
  "domains": ["https://www.relaxandsmile.com/"]
}
```

Manual domains do not inherit Google Maps profile fields. If critical profile or contact data cannot be established, the result fails closed instead of being presented as a qualified lead.

### Website audit behavior

The auditor fetches public HTML and same-host contact or booking pages. It does not execute JavaScript.

| Outcome | `auditStatus` | Commercial behavior |
|---|---|---|
| Valid homepage | `success` | Verified checks may score |
| Valid homepage with a secondary-page failure | `partial` | Verified checks only |
| Commercially unresolved sparse homepage | `partial` | Absence checks remain unknown; no false gap scoring |
| Timeout, DNS, TLS, blocked response, 4xx/5xx, empty body, or non-HTML | `failed` | Cannot qualify |
| Trusted Maps record explicitly has no website | `no_website` | Source-backed no-website evidence may score |
| Audit disabled or source website field is unknown | `skipped` | Cannot qualify |

Unknown evidence is preserved as `null`:

```text
null  = unknown, unavailable, or not checked
false = checked and absent
true  = checked and present
```

Failed and skipped audits never qualify. Disabled booking, contact, or chat checks block website qualification because required evidence would be missing.

### Opportunity scoring and services

`opportunityScore` measures observed commercial gaps from 0 to 100. `confidenceScore` measures technical evidence confidence; it does not claim that the business profile is complete.

Verified checks include online booking, booking providers and URLs, contact form/page, CTA, chat, WhatsApp, HTTPS, mobile viewport, Google Analytics, Google Tag Manager, Meta Pixel, and other technology signals.

`targetService` supports:

- automatic selection, prioritizing booking and lead capture;
- online booking;
- website redesign;
- lead capture;
- tracking;
- CRM automation.

An explicit service is recommended only when matching evidence exists.

### Languages

`outputLanguage` supports English, Brazilian Portuguese, and Spanish. It controls evidence, score explanations, service recommendations, gap summaries, and outreach copy.

### Deduplication and bounded processing

Deduplication priority is Google Maps place ID, canonical website hostname, normalized phone, then normalized name plus a non-empty address. A name without an address is not sufficient to merge records.

Discovery is streamed. Processing occurs in bounded batches and concurrency-sized waves. When the user spending limit is reached, the Actor stops starting new work and records unpublished items in the summary.

### Security and responsible use

Before each homepage, redirect, or secondary request, the Actor validates the URL and DNS target, blocks private and metadata addresses, checks every redirect, limits response size, validates content type, and keeps secondary crawling on the same normalized hostname.

The Actor audits publicly accessible business information. Users are responsible for complying with applicable privacy, marketing, outreach, and data-protection laws. Review the evidence and the target jurisdiction's rules before contacting a business.

### Limitations

- JavaScript-rendered forms and widgets may not appear in source HTML.
- Detection is heuristic and should be reviewed before outreach.
- Public-email extraction does not prove deliverability or mailbox ownership.
- The Maps provider is an external Actor with its own schema and lifecycle.
- Dataset storage is append-only.

### Development and validation

```powershell
python -m compileall src scripts
python -m ruff check .
python -m mypy src
python -m pytest -v
python scripts/validate_schemas.py
apify validate-schema
docker build -t local-business-opportunity-finder .
```

GitHub Actions validates dependencies, tests, coverage, lint, types, schemas, Docker, and mock integration. Cost-bearing live validation requires an `APIFY_TOKEN` secret and an explicit spending ceiling.

### Support

When reporting a problem, include the Actor run ID, input mode, redacted input, relevant dataset item, expected behavior, and observed behavior.

The technical Actor slug remains `local-business-funnel-gap-finder`.

# Actor input Schema

## `inputMode` (type: `string`):

Google Maps search is the fastest way to start. You can also import an Apify dataset, business objects, or website domains.

## `searchQueries` (type: `array`):

Used in Google Maps mode. Use a niche plus a US city and state, for example auto repair shops in Tampa FL.

## `maxResultsPerQuery` (type: `integer`):

Maximum number of Google Maps businesses requested for each search.

## `targetService` (type: `string`):

Automatic prioritizes booking and lead-capture offers while requiring matching website evidence before recommending a service.

## `includeNearMisses` (type: `boolean`):

Publishes contactable businesses that pass every quality gate but score from the near-miss floor through 39 to a separate dataset. These rows do not trigger the qualified-opportunity event.

## `outputLanguage` (type: `string`):

Controls evidence, service recommendations, gap summaries, and channel-specific outreach.

## `mapsProviderActorId` (type: `string`):

Current verified default: compass/crawler-google-places.

## `maxTotalResults` (type: `integer`):

Hard cap applied to every input mode.

## `maxDiscoveryCostUsd` (type: `string`):

Passed as a Decimal to the child Actor. The current default provider requires at least USD 0.50 per run.

## `discoveryTimeoutSeconds` (type: `integer`):

Maximum child Actor runtime before the Maps call is stopped.

## `discoveryMemoryMbytes` (type: `integer`):

Memory allocated to the Maps child Actor.

## `apifyDatasetId` (type: `string`):

Required only in dataset mode.

## `businesses` (type: `array`):

Required only in businesses mode. Recognized fields are documented below and additional source fields are accepted as upstream metadata.

## `domains` (type: `array`):

Required only in domains mode. Only public HTTP and HTTPS targets are audited.

## `websiteField` (type: `string`):

Custom website field used by dataset and businesses modes.

## `nameField` (type: `string`):

Custom business name field used by dataset and businesses modes.

## `phoneField` (type: `string`):

Custom phone field used by dataset and businesses modes.

## `categoryField` (type: `string`):

Custom category field used by dataset and businesses modes.

## `auditWebsite` (type: `boolean`):

When false, records are marked skipped and no website request is made.

## `detectBooking` (type: `boolean`):

When disabled, booking output is null and booking never affects score, service, pitch, gaps, or confidence. Website records cannot qualify while this required evidence check is disabled.

## `detectContactForm` (type: `boolean`):

When disabled, contact outputs are null and never affect commercial output. Website records cannot qualify while these required evidence checks are disabled.

## `detectChatOrWhatsApp` (type: `boolean`):

When disabled, chat and WhatsApp outputs are null and never affect commercial output. Website records cannot qualify while these required evidence checks are disabled.

## `generatePitchAngle` (type: `boolean`):

Legacy compatibility option. Sales-ready leads and near misses always include complete channel-specific outreach. This flag only affects optional outreach for non-candidates when generateOutreachForAllResults is also enabled.

## `generateOutreachForAllResults` (type: `boolean`):

Legacy research option. When false, outreach is generated only for records that meet the configured publication contract.

## `maxPagesPerWebsite` (type: `integer`):

Only same-host contact or booking pages are fetched.

## `maxConcurrency` (type: `integer`):

Maximum number of website audits allowed to run concurrently.

## `batchSize` (type: `integer`):

Maximum records retained per batch. Processing occurs in concurrency-sized waves so spending-limit termination does not start the entire batch at once.

## `minimumOpportunityScore` (type: `integer`):

Fixed at 40 so changing an input cannot bypass qualified-opportunity charging or reclassify sales-ready rows as research output without that event.

## `nearMissMinimumOpportunityScore` (type: `integer`):

Contactable records scoring from this value through 39, and still below the configured qualification threshold, are published to the separate near\_misses dataset.

## `minimumConfidenceScore` (type: `number`):

Hard technical evidence-confidence floor. Values below 0.90 from legacy API inputs are safely raised to 0.90.

## `minimumInformationCompletenessScore` (type: `number`):

Hard floor for known, valid and applicable business-profile information. The website-audit group retains a separate hard floor of 0.87, and qualified commercial output must be complete.

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

Sales-ready leads always go to the default dataset and near misses to their own dataset. Choose all\_audits only when you also want every outcome in the separate audit\_results dataset.

## `onlyReturnOpportunities` (type: `boolean`):

Legacy compatibility option. When outputMode is omitted, true selects qualified\_only and false selects all\_audits. Conflicting explicit values are rejected. New inputs should use outputMode.

## Actor input object example

```json
{
  "inputMode": "maps_search",
  "searchQueries": [
    "auto repair shops in Tampa FL"
  ],
  "maxResultsPerQuery": 50,
  "targetService": "auto",
  "includeNearMisses": true,
  "outputLanguage": "en",
  "mapsProviderActorId": "compass/crawler-google-places",
  "maxTotalResults": 500,
  "maxDiscoveryCostUsd": "2.00",
  "discoveryTimeoutSeconds": 900,
  "discoveryMemoryMbytes": 512,
  "businesses": [
    {
      "title": "Relax and Smile Dental Care",
      "website": "https://www.relaxandsmile.com/",
      "category": "Dentist",
      "rating": 4.9,
      "reviewsCount": 500
    }
  ],
  "domains": [
    "https://www.relaxandsmile.com/"
  ],
  "websiteField": "website",
  "nameField": "title",
  "phoneField": "phone",
  "categoryField": "category",
  "auditWebsite": true,
  "detectBooking": true,
  "detectContactForm": true,
  "detectChatOrWhatsApp": true,
  "generatePitchAngle": true,
  "generateOutreachForAllResults": false,
  "maxPagesPerWebsite": 5,
  "maxConcurrency": 5,
  "batchSize": 25,
  "minimumOpportunityScore": 40,
  "nearMissMinimumOpportunityScore": 25,
  "minimumConfidenceScore": 0.9,
  "minimumInformationCompletenessScore": 0.85,
  "outputMode": "qualified_only"
}
```

# Actor output Schema

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

Backward-compatible alias for integrations that read output.results.

## `qualifiedLeads` (type: `string`):

Contactable businesses that passed the commercial score, evidence, profile, audit, and outreach quality gates. Each published row triggers the qualified-opportunity event.

## `nearMisses` (type: `string`):

Contactable, high-quality businesses that passed every quality gate and scored from the configured near-miss floor through 39. These rows do not trigger the qualified-opportunity event.

## `auditResults` (type: `string`):

All audit outcomes when outputMode is all\_audits. Rows that are neither qualified nor near misses retain technical diagnostics but have usable contacts and commercial copy redacted.

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

Discovery, rejected input, deduplication, audit, output, PPE charging, and child Maps Actor cost reconciliation.

# 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 = {
    "searchQueries": [
        "auto repair shops in Tampa FL"
    ],
    "businesses": [
        {
            "title": "Relax and Smile Dental Care",
            "website": "https://www.relaxandsmile.com/",
            "category": "Dentist",
            "rating": 4.9,
            "reviewsCount": 500
        }
    ],
    "domains": [
        "https://www.relaxandsmile.com/"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("lirafrt/local-business-funnel-gap-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 = {
    "searchQueries": ["auto repair shops in Tampa FL"],
    "businesses": [{
            "title": "Relax and Smile Dental Care",
            "website": "https://www.relaxandsmile.com/",
            "category": "Dentist",
            "rating": 4.9,
            "reviewsCount": 500,
        }],
    "domains": ["https://www.relaxandsmile.com/"],
}

# Run the Actor and wait for it to finish
run = client.actor("lirafrt/local-business-funnel-gap-finder").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 '{
  "searchQueries": [
    "auto repair shops in Tampa FL"
  ],
  "businesses": [
    {
      "title": "Relax and Smile Dental Care",
      "website": "https://www.relaxandsmile.com/",
      "category": "Dentist",
      "rating": 4.9,
      "reviewsCount": 500
    }
  ],
  "domains": [
    "https://www.relaxandsmile.com/"
  ]
}' |
apify call lirafrt/local-business-funnel-gap-finder --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=lirafrt/local-business-funnel-gap-finder",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Google Maps Lead Qualifier | Website Gaps + Outreach",
        "description": "Turn Google Maps results or existing business lists into qualified sales opportunities. Audit public websites, detect booking and lead-generation gaps, rank leads by confidence, recommend services, and generate evidence-backed outreach.",
        "version": "2.4",
        "x-build-id": "4zjgFpr8Cdx6jgKVe"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/lirafrt~local-business-funnel-gap-finder/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-lirafrt-local-business-funnel-gap-finder",
                "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/lirafrt~local-business-funnel-gap-finder/runs": {
            "post": {
                "operationId": "runs-sync-lirafrt-local-business-funnel-gap-finder",
                "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/lirafrt~local-business-funnel-gap-finder/run-sync": {
            "post": {
                "operationId": "run-sync-lirafrt-local-business-funnel-gap-finder",
                "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": {
                    "inputMode": {
                        "title": "Input mode",
                        "enum": [
                            "maps_search",
                            "dataset",
                            "businesses",
                            "domains"
                        ],
                        "type": "string",
                        "description": "Google Maps search is the fastest way to start. You can also import an Apify dataset, business objects, or website domains.",
                        "default": "maps_search"
                    },
                    "searchQueries": {
                        "title": "Google Maps search queries",
                        "maxItems": 100,
                        "uniqueItems": true,
                        "type": "array",
                        "description": "Used in Google Maps mode. Use a niche plus a US city and state, for example auto repair shops in Tampa FL.",
                        "items": {
                            "type": "string",
                            "minLength": 1
                        },
                        "default": []
                    },
                    "maxResultsPerQuery": {
                        "title": "Leads per search",
                        "minimum": 1,
                        "maximum": 500,
                        "type": "integer",
                        "description": "Maximum number of Google Maps businesses requested for each search.",
                        "default": 50
                    },
                    "targetService": {
                        "title": "Service you sell",
                        "enum": [
                            "auto",
                            "online_booking",
                            "website_redesign",
                            "lead_capture",
                            "tracking",
                            "crm_automation"
                        ],
                        "type": "string",
                        "description": "Automatic prioritizes booking and lead-capture offers while requiring matching website evidence before recommending a service.",
                        "default": "auto"
                    },
                    "includeNearMisses": {
                        "title": "Include high-quality near misses",
                        "type": "boolean",
                        "description": "Publishes contactable businesses that pass every quality gate but score from the near-miss floor through 39 to a separate dataset. These rows do not trigger the qualified-opportunity event.",
                        "default": true
                    },
                    "outputLanguage": {
                        "title": "Outreach language",
                        "enum": [
                            "en",
                            "pt-BR",
                            "es"
                        ],
                        "type": "string",
                        "description": "Controls evidence, service recommendations, gap summaries, and channel-specific outreach.",
                        "default": "en"
                    },
                    "mapsProviderActorId": {
                        "title": "Maps provider Actor ID",
                        "minLength": 1,
                        "type": "string",
                        "description": "Current verified default: compass/crawler-google-places.",
                        "default": "compass/crawler-google-places"
                    },
                    "maxTotalResults": {
                        "title": "Maximum total results",
                        "minimum": 1,
                        "maximum": 5000,
                        "type": "integer",
                        "description": "Hard cap applied to every input mode.",
                        "default": 500
                    },
                    "maxDiscoveryCostUsd": {
                        "title": "Maximum Maps discovery charge in USD",
                        "pattern": "^[0-9]+(\\.[0-9]{1,4})?$",
                        "type": "string",
                        "description": "Passed as a Decimal to the child Actor. The current default provider requires at least USD 0.50 per run.",
                        "default": "2.00"
                    },
                    "discoveryTimeoutSeconds": {
                        "title": "Maps discovery timeout in seconds",
                        "minimum": 60,
                        "maximum": 3600,
                        "type": "integer",
                        "description": "Maximum child Actor runtime before the Maps call is stopped.",
                        "default": 900
                    },
                    "discoveryMemoryMbytes": {
                        "title": "Child Actor memory in MB",
                        "minimum": 128,
                        "maximum": 4096,
                        "type": "integer",
                        "description": "Memory allocated to the Maps child Actor.",
                        "default": 512
                    },
                    "apifyDatasetId": {
                        "title": "Apify dataset",
                        "type": "string",
                        "description": "Required only in dataset mode."
                    },
                    "businesses": {
                        "title": "Business objects",
                        "maxItems": 5000,
                        "type": "array",
                        "description": "Required only in businesses mode. Recognized fields are documented below and additional source fields are accepted as upstream metadata.",
                        "items": {
                            "type": "object",
                            "additionalProperties": true,
                            "properties": {
                                "title": {
                                    "title": "Business title",
                                    "type": "string",
                                    "description": "Primary business name, commonly returned by Google Maps datasets.",
                                    "nullable": true
                                },
                                "name": {
                                    "title": "Business name",
                                    "type": "string",
                                    "description": "Alternative field containing the business name.",
                                    "nullable": true
                                },
                                "businessName": {
                                    "title": "Business name alias",
                                    "type": "string",
                                    "description": "Normalized or custom business-name field.",
                                    "nullable": true
                                },
                                "website": {
                                    "title": "Website",
                                    "type": "string",
                                    "description": "Public business website URL or domain.",
                                    "nullable": true
                                },
                                "websiteUrl": {
                                    "title": "Website URL alias",
                                    "type": "string",
                                    "description": "Alternative field containing the public business website URL.",
                                    "nullable": true
                                },
                                "phone": {
                                    "title": "Phone",
                                    "type": "string",
                                    "description": "Public business phone number.",
                                    "nullable": true
                                },
                                "category": {
                                    "title": "Category",
                                    "type": "string",
                                    "description": "Business category or industry label.",
                                    "nullable": true
                                },
                                "address": {
                                    "title": "Address",
                                    "type": "string",
                                    "description": "Public business address.",
                                    "nullable": true
                                },
                                "rating": {
                                    "title": "Rating",
                                    "type": "number",
                                    "description": "Business rating from 0 to 5.",
                                    "nullable": true,
                                    "minimum": 0,
                                    "maximum": 5
                                },
                                "totalScore": {
                                    "title": "Total score alias",
                                    "type": "number",
                                    "description": "Alternative rating field from 0 to 5.",
                                    "nullable": true,
                                    "minimum": 0,
                                    "maximum": 5
                                },
                                "reviewsCount": {
                                    "title": "Reviews count",
                                    "type": "integer",
                                    "description": "Number of public reviews.",
                                    "nullable": true,
                                    "minimum": 0
                                },
                                "reviewCount": {
                                    "title": "Review count alias",
                                    "type": "integer",
                                    "description": "Alternative field containing the number of public reviews.",
                                    "nullable": true,
                                    "minimum": 0
                                }
                            }
                        },
                        "default": []
                    },
                    "domains": {
                        "title": "Domains or website URLs",
                        "maxItems": 5000,
                        "uniqueItems": true,
                        "type": "array",
                        "description": "Required only in domains mode. Only public HTTP and HTTPS targets are audited.",
                        "items": {
                            "type": "string",
                            "minLength": 1
                        },
                        "default": []
                    },
                    "websiteField": {
                        "title": "Website field alias",
                        "minLength": 1,
                        "type": "string",
                        "description": "Custom website field used by dataset and businesses modes.",
                        "default": "website"
                    },
                    "nameField": {
                        "title": "Business name field alias",
                        "minLength": 1,
                        "type": "string",
                        "description": "Custom business name field used by dataset and businesses modes.",
                        "default": "title"
                    },
                    "phoneField": {
                        "title": "Phone field alias",
                        "minLength": 1,
                        "type": "string",
                        "description": "Custom phone field used by dataset and businesses modes.",
                        "default": "phone"
                    },
                    "categoryField": {
                        "title": "Category field alias",
                        "minLength": 1,
                        "type": "string",
                        "description": "Custom category field used by dataset and businesses modes.",
                        "default": "category"
                    },
                    "auditWebsite": {
                        "title": "Audit websites",
                        "type": "boolean",
                        "description": "When false, records are marked skipped and no website request is made.",
                        "default": true
                    },
                    "detectBooking": {
                        "title": "Detect online booking",
                        "type": "boolean",
                        "description": "When disabled, booking output is null and booking never affects score, service, pitch, gaps, or confidence. Website records cannot qualify while this required evidence check is disabled.",
                        "default": true
                    },
                    "detectContactForm": {
                        "title": "Detect contact forms and pages",
                        "type": "boolean",
                        "description": "When disabled, contact outputs are null and never affect commercial output. Website records cannot qualify while these required evidence checks are disabled.",
                        "default": true
                    },
                    "detectChatOrWhatsApp": {
                        "title": "Detect chat and WhatsApp",
                        "type": "boolean",
                        "description": "When disabled, chat and WhatsApp outputs are null and never affect commercial output. Website records cannot qualify while these required evidence checks are disabled.",
                        "default": true
                    },
                    "generatePitchAngle": {
                        "title": "Generate outreach for research results",
                        "type": "boolean",
                        "description": "Legacy compatibility option. Sales-ready leads and near misses always include complete channel-specific outreach. This flag only affects optional outreach for non-candidates when generateOutreachForAllResults is also enabled.",
                        "default": true
                    },
                    "generateOutreachForAllResults": {
                        "title": "Generate outreach for all scored results",
                        "type": "boolean",
                        "description": "Legacy research option. When false, outreach is generated only for records that meet the configured publication contract.",
                        "default": false
                    },
                    "maxPagesPerWebsite": {
                        "title": "Maximum secondary pages per website",
                        "minimum": 1,
                        "maximum": 20,
                        "type": "integer",
                        "description": "Only same-host contact or booking pages are fetched.",
                        "default": 5
                    },
                    "maxConcurrency": {
                        "title": "Maximum concurrent website audits",
                        "minimum": 1,
                        "maximum": 50,
                        "type": "integer",
                        "description": "Maximum number of website audits allowed to run concurrently.",
                        "default": 5
                    },
                    "batchSize": {
                        "title": "Streaming batch size",
                        "minimum": 1,
                        "maximum": 100,
                        "type": "integer",
                        "description": "Maximum records retained per batch. Processing occurs in concurrency-sized waves so spending-limit termination does not start the entire batch at once.",
                        "default": 25
                    },
                    "minimumOpportunityScore": {
                        "title": "Qualified opportunity score",
                        "minimum": 40,
                        "maximum": 40,
                        "type": "integer",
                        "description": "Fixed at 40 so changing an input cannot bypass qualified-opportunity charging or reclassify sales-ready rows as research output without that event.",
                        "default": 40
                    },
                    "nearMissMinimumOpportunityScore": {
                        "title": "Near-miss opportunity floor",
                        "minimum": 25,
                        "maximum": 39,
                        "type": "integer",
                        "description": "Contactable records scoring from this value through 39, and still below the configured qualification threshold, are published to the separate near_misses dataset.",
                        "default": 25
                    },
                    "minimumConfidenceScore": {
                        "title": "Minimum evidence confidence",
                        "minimum": 0.9,
                        "maximum": 1,
                        "type": "number",
                        "description": "Hard technical evidence-confidence floor. Values below 0.90 from legacy API inputs are safely raised to 0.90.",
                        "default": 0.9
                    },
                    "minimumInformationCompletenessScore": {
                        "title": "Minimum profile completeness",
                        "minimum": 0.85,
                        "maximum": 1,
                        "type": "number",
                        "description": "Hard floor for known, valid and applicable business-profile information. The website-audit group retains a separate hard floor of 0.87, and qualified commercial output must be complete.",
                        "default": 0.85
                    },
                    "outputMode": {
                        "title": "Audit evidence output",
                        "enum": [
                            "qualified_only",
                            "all_audits"
                        ],
                        "type": "string",
                        "description": "Sales-ready leads always go to the default dataset and near misses to their own dataset. Choose all_audits only when you also want every outcome in the separate audit_results dataset.",
                        "default": "qualified_only"
                    },
                    "onlyReturnOpportunities": {
                        "title": "Return only qualified opportunities",
                        "type": "boolean",
                        "description": "Legacy compatibility option. When outputMode is omitted, true selects qualified_only and false selects all_audits. Conflicting explicit values are rejected. New inputs should use outputMode."
                    }
                }
            },
            "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
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
