# Find Local Businesses With No Website - Web Designer Leads (`seibs.co/local-leads-without-websites`) Actor

Find US local businesses on Google Maps with no website or weak web presence (social-only, free Wix, GMB-only, parked). Per-record quality score, 50-vertical inference, per-vertical intent signals. URL-pattern classification, no live fetches. For web designers and SEO agencies.

- **URL**: https://apify.com/seibs.co/local-leads-without-websites.md
- **Developed by:** [Seibs.co](https://apify.com/seibs.co) (community)
- **Categories:** Lead generation, Business, Marketing
- **Stats:** 14 total users, 9 monthly users, 93.3% runs succeeded, NaN bookmarks
- **User rating**: No ratings yet

## Pricing

from $25.00 / 1,000 prospect records

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

## Local Leads Without Websites

<!-- TOP-SELL-START -->
> **TL;DR for web designers, freelance devs, local SEO agencies, and digital marketing consultants:** Pulls local Google Maps businesses that have NO website or only a weak Facebook-page or Linktree as their web presence, sorted by lead-quality score (reviews x recency x category). Compared to compass/crawler-google-places, this pre-filters to businesses that are demonstrably underserved on web (no domain, no SSL, broken site, or only social-link) so every record is a real pitch opportunity rather than a high-quality enterprise lead. Free Apify plan returns about 1,000 leads per month on your $5 platform credit, then demo samples plus an upgrade message. Upgrade to Apify Starter ($49/mo) for unlimited volume.

### Run it in 30 seconds

```python
## Via the Apify Python SDK
from apify_client import ApifyClient

client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("seibs.co/local-leads-without-websites").call(run_input={
    "locations": [
        "Panama City, FL"
    ],
    "mode": "no_website",
    "min_quality_score": 50,
    "max_results_per_query": 100
})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)
````

Or via curl:

```bash
curl -X POST "https://api.apify.com/v2/acts/seibs.co~local-leads-without-websites/run-sync-get-dataset-items?token=<YOUR_APIFY_TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{"locations": ["Panama City, FL"], "mode": "no_website", "min_quality_score": 50, "max_results_per_query": 100}'
```

Or click "Try for free" on this page if you prefer the no-code UI.

### What you get

Each run produces:

- A clean dataset, filterable in the Apify console and downloadable as CSV or JSON
- An OUTPUT.html dashboard preview of your top records
- A sample-output preview at [`.actor/sample-output.json`](./.actor/sample-output.json)

Per-archetype custom artifacts shipped with this actor:

- top-leads.csv (sorted by quality\_score, with phone and current-web-presence columns)
- pitch-templates.html (per-vertical web-design proposal with copy-to-clipboard buttons)
- weak-web-presence.csv (subset with Facebook-only or Linktree-only sites)

***

### 1. Who this is for

- Independent web designers and small agencies selling one-off websites.
- Local SEO firms that bundle GMB optimization with a Wix-to-WordPress rebuild.
- Marketing freelancers building a cold-call list of local prospects.

### 2. What it does

For every (search term x location) pair, the actor:

1. Calls `compass/crawler-google-places` to enumerate businesses on Maps.
2. Drops national chains and franchises (Great Clips, McDonald's, Home Depot, Marriott, etc.) by name match against a curated ~400-brand blocklist. Runs BEFORE the website check so franchises whose Maps listing is missing a website field do not leak through as "no website" prospects. Toggle off via `exclude_chains: false`.
3. Classifies the `website` field on each record into one of 12 buckets (real site, social-only, free Wix / Squarespace / GoDaddy, GMB-only, linktree, parked domain, or none).
4. Computes a `quality_score` (0.0 to 1.0) from reviews, rating, claimed-flag, phone, and review recency.
5. Filters out businesses that already have a real website (the whole point of the actor).
6. Pushes records to the dataset and charges per-record PPE events.

### 3. Key inputs

| Field | Required | Default | Notes |
|---|---|---|---|
| `locations` | yes | - | US city + state, neighborhood, or ZIP. Up to 25. |
| `mode` | no | `all_businesses` | Or `vertical_filter` to restrict to selected verticals. |
| `verticals` | no | `[]` | Up to 50 of the supported verticals. Used when `mode=vertical_filter`. |
| `radius_miles` | no | `25` | Soft hint passed through to Maps (5 to 50). |
| `weak_website_filter` | no | `include_weak_websites` | `include_weak_websites` | `exclude_weak_websites` | `only_zero_website`. |
| `min_quality_score` | no | `0` | Drop records below this score (0.0 to 1.0). |
| `max_results_per_query` | no | `50` | Cap per (term x location) tuple. Max 100. |
| `sort_by` | no | `quality_score_desc` | Also: `reviews_count_desc`, `rating_desc`, `name_asc`. |
| `search_terms` | no | derived | Free-text override. If empty, derived from `mode` + `verticals`. |
| `exclude_chains` | no | `true` | Drops national chains and franchises (Great Clips, McDonald's, Home Depot, Marriott, etc.) regardless of whether their Maps listing has a website field. ~400 brands blocked. |

### 4. Output record (excerpt)

```json
{
  "place_id": "ChIJN1t_tDeuEmsRUsoyG83frY4",
  "name": "Cortez Family Diner",
  "vertical": "restaurants",
  "address": { "city": "Austin", "state": "TX", "zip": "78702" },
  "phone_e164": "+15125550181",
  "web_presence_type": "facebook_only",
  "web_presence_url": "https://www.facebook.com/cortezfamilydiner",
  "quality_score": 0.83,
  "is_high_quality": true,
  "vertical_signals": { "has_online_ordering": false, "has_reservations": false }
}
```

Five named views: `overview` (8 fields), `detailed` (every field), `signals` (unwound by vertical signal), MCP-compatible JSON, and a CSV export.

### 5. Pricing (tiered by Apify subscription plan)

| Event | DIAMOND | FREE |
|---|---|---|
| `prospect_record` (primary) | $0.020 | $0.050 |
| `high_quality_prospect` (when quality\_score >= 0.75) | $0.030 | $0.075 |
| `web_presence_classification` (when web\_presence\_type != has\_real\_website) | $0.003 | $0.0075 |

Apify margin: 20%.

### 6. Cost control (wired in)

- Proactive free-plan check before the paid upstream call.
- Soft-fail demo on credit-exhausted - exits SUCCEEDED with labeled samples.
- 24h KVStore query cache (identical inputs in a 24h window skip the upstream call entirely).
- Run-budget guard: 20-min wall clock, 50-attempt + low-revenue abort, 200 hard record cap.
- Pre-flight input limits: max 25 locations, max 100 results per query, max 50 verticals.

### 7. FAQ

**Why don't you visit the prospect's website to check if it's parked?**
Live-fetching every URL would multiply compute cost by 10x and slow runs by orders of magnitude. The URL-pattern classifier catches the vast majority of weak-web cases. v2 may add an optional `verify_live` flag for buyers who want to confirm parked-domain hits.

**Why was my local Great Clips / Home Depot / McDonald's showing up before?**
Franchise locations on Google Maps sometimes have NO `website` field on the individual Maps listing (the corporate brand owns the website, the franchisee doesn't have their own URL there). The classifier saw "no website" and emitted them. Fixed in the current version: the actor drops ~400 chain brands by name match BEFORE the website check, so franchises never leak through as prospects. Toggle off with `exclude_chains: false` if you want them back.

**Why is `has_real_website` filtered out by default?**
The entire premise of this actor is finding prospects to sell a website to. A business that already has a real website is not the target.

**Can I run this for non-US locations?**
Compass supports global coverage but the verticals and quality scoring are tuned for US small business. International runs work but may misclassify edge cases.

**Why a quality score and not just review count?**
A 5-star business with 3 reviews is not the same prospect as a 4.6-star business with 200 reviews. The score combines reviews\_count (log scaled), rating, claimed-flag, phone, and recency into one number.

### 8. Related Actors

This actor lives in a 35+ actor portfolio. After exporting your list of prospects, layer additional intent and verified contact data with:

- **B2B Sales Triggers** - hiring surge, funding, press, exec changes (intent signals).
- **Email Verifier (Batch)** - validate any emails you append from your CRM.
- **Home Services Lead Finder** - if you want POS / booking / tech-stack signals for home-services prospects.

See the full portfolio: https://apify.com/seibs.co

### Integrations

- **Apify API** - GET `/v2/datasets/{id}/items?view=overview` for SDR-friendly columns.
- **Zapier / Make / n8n** - subscribe to the run-finished webhook; pipe the `overview` view into a Google Sheet or CRM.
- **MCP** - point a Claude Desktop / Cursor / OpenAI Assistants tool call at the `datasetItemsMcp` URL.
- **CSV** - direct CSV download URL is published in `output_schema.json`.

### Save your input as an Apify Task

Apify Tasks let you save a configured input once and re-run it with a single click - no need to re-type search terms, locations, filters, or tier settings every time. Tasks are the foundation for everything that comes next: schedules, monitor mode, and webhook routing all attach to a saved Task, not to the raw actor.

Steps to save your current input as a Task:

1. On this actor's Apify Store page, click `Run` with your input fully configured.
2. Click the `Save as task` button at the top of the run page.
3. Name the task something memorable (e.g. `Plumbers with no website in Houston, TX - weekly`).
4. Reload the task page and click `Start` anytime to re-run with the same inputs.

Tasks unlock the next two features below: scheduling and monitor mode.

### Run this weekly with Apify Schedules

Apify Schedules cron-run any saved Task automatically. Pair this with the saved Task above and you get hands-off recurring runs with no manual clicks, no missed weeks, and a steady stream of fresh data into your CRM or warehouse.

Steps to schedule a Task:

1. Save your input as a Task (see above).
2. Go to https://console.apify.com/schedules and click `Create new schedule`.
3. Pick your Task and set the cron expression. Common patterns:
   - Daily at 9am UTC: `0 9 * * *`
   - Weekly on Mondays at 9am: `0 9 * * 1`
   - Monthly on the 1st: `0 9 1 * *`
4. Save. Apify will run your Task on that schedule automatically, push the dataset to whatever integrations you have wired up, and fire run-completion webhooks for downstream automation.

Run weekly to keep your no-website prospect list fresh and catch newly-claimed Google Maps listings that still lack a site.

### Monitor mode (v2, beta)

Monitor mode is the v2 evolution of this actor and is currently in BETA. It turns a recurring schedule into a true change-feed instead of a firehose of duplicate records.

How it works:

- When this actor runs under an Apify Schedule, monitor mode is enabled automatically.
- Instead of emitting ALL records every run, it emits ONLY records that are NEW or CHANGED since the last scheduled run.
- A digest record summarizes the delta (X new, Y changed, Z removed) at the top of every run.
- Optional: provide a Slack or email webhook URL in the `monitor_webhook_url` input field and the digest fires there too, so your team gets the delta in their inbox or channel without polling the dataset.
- Cost: a single `scheduled_delta_run` event ($0.05) per scheduled run, plus standard PPE on emitted delta records only. Predictable monthly cost, no surprise bills from re-charging for unchanged records.

Monitor mode is rolling out to the top 3 actors first (this one included if it's hotel-motel-lead-finder, google-maps-reviews-pro, or mcp-accounting-firm-leads). Full portfolio coverage by end of June.

# Actor input Schema

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

all\_businesses: scrape any business type in the location, then classify by Maps category. vertical\_filter: restrict to the verticals you select below.

## `verticals` (type: `array`):

Restrict to these business verticals. Ignored when mode = all\_businesses. Leave empty to include every supported vertical.

## `locations` (type: `array`):

US locations to search. Accepts city + state (e.g. 'Austin, TX') OR a 5-digit ZIP (e.g. '78701'). Up to 25 locations per run.

## `radius_miles` (type: `integer`):

Approximate radius (miles) applied to each location. Compass uses this as a soft hint; the actual area depends on Google Maps zoom logic.

## `weak_website_filter` (type: `string`):

include\_weak\_websites: emit prospects with no website AND prospects with weak web presence (social-only, free Wix, GMB-only, etc.). This is the broadest pool. exclude\_weak\_websites: emit ONLY prospects with no website field on the Maps record. only\_zero\_website: strictest -- exactly the same as exclude\_weak\_websites today (kept distinct so a future v2 can split parked vs. fully-absent).

## `min_quality_score` (type: `number`):

Filter records below this quality score (0.0 to 1.0). 0.0 emits everything; 0.75 is the 'high-quality' threshold; 0.5 is a good middle ground when you want to skip 5-review, unclaimed listings.

## `max_results_per_query` (type: `integer`):

Cap on records returned per (search\_term x location) tuple. Compass enforces a hard ceiling; we cap at 100 to protect compute budget.

## `sort_by` (type: `string`):

Order of the emitted records. quality\_score\_desc is the recommended default for prospecting.

## `search_terms` (type: `array`):

Free-text Google Maps search terms. Combined with each location. If empty, terms are derived from the mode + verticals selection. Example: \['small business', 'local shop'].

## `exclude_chains` (type: `boolean`):

When true (default), drops records whose business name matches a national chain or franchise brand (Great Clips, McDonald's, Home Depot, Marriott, etc.). Chains are dropped BEFORE the no-website check, so franchise locations whose Maps listing happens to be missing a website field do NOT leak through. Turn off only if you specifically want chain locations in the output (e.g. you sell to franchisees, not independent businesses). Blocklist covers ~400 common US chains (900+ spelling variants) across fast food, grocery, gas/convenience, big box, auto, hotels, banks, salons, fitness, real estate, etc.

## Actor input object example

```json
{
  "mode": "all_businesses",
  "verticals": [],
  "locations": [
    "Austin, TX"
  ],
  "radius_miles": 25,
  "weak_website_filter": "include_weak_websites",
  "min_quality_score": 0,
  "max_results_per_query": 50,
  "sort_by": "quality_score_desc",
  "search_terms": [],
  "exclude_chains": true
}
```

# Actor output Schema

## `datasetItems` (type: `string`):

Narrow, token-efficient slice of every record. Consumer: LLM agents (Claude, GPT, LangChain tools), MCP hosts, dashboards. Skim fields: name, vertical, city/state, phone\_e164, web\_presence\_type, quality\_score, is\_high\_quality.

## `datasetItemsDetailed` (type: `string`):

All fields for every record. Consumer: humans browsing the dataset in the Apify UI, RAG ingest pipelines, full backups. Larger payload - not recommended as a direct LLM tool response.

## `datasetItemsUnwind` (type: `string`):

Same records, but each detected vertical\_signals key/value pair is promoted to its own row. Consumer: Zapier / Make / n8n / Google Sheets users who want one row per signal, and LLM agents that prefer flat rows over nested objects.

## `datasetItemsMcp` (type: `string`):

First 50 overview records as a clean JSON array. Wrap on the agent side in an MCP tool-call response envelope. Consumer: MCP servers, Claude Desktop, Cursor, OpenAI Assistants tool calls.

## `datasetItemsCsv` (type: `string`):

Spreadsheet-friendly export of the overview view. Consumer: humans, sales ops teams, Excel / Google Sheets users.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "mode": "all_businesses",
    "locations": [
        "Austin, TX"
    ],
    "radius_miles": 25,
    "weak_website_filter": "include_weak_websites",
    "min_quality_score": 0,
    "max_results_per_query": 50,
    "sort_by": "quality_score_desc",
    "search_terms": [],
    "exclude_chains": true
};

// Run the Actor and wait for it to finish
const run = await client.actor("seibs.co/local-leads-without-websites").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "mode": "all_businesses",
    "locations": ["Austin, TX"],
    "radius_miles": 25,
    "weak_website_filter": "include_weak_websites",
    "min_quality_score": 0,
    "max_results_per_query": 50,
    "sort_by": "quality_score_desc",
    "search_terms": [],
    "exclude_chains": True,
}

# Run the Actor and wait for it to finish
run = client.actor("seibs.co/local-leads-without-websites").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 '{
  "mode": "all_businesses",
  "locations": [
    "Austin, TX"
  ],
  "radius_miles": 25,
  "weak_website_filter": "include_weak_websites",
  "min_quality_score": 0,
  "max_results_per_query": 50,
  "sort_by": "quality_score_desc",
  "search_terms": [],
  "exclude_chains": true
}' |
apify call seibs.co/local-leads-without-websites --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=seibs.co/local-leads-without-websites",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Find Local Businesses With No Website - Web Designer Leads",
        "description": "Find US local businesses on Google Maps with no website or weak web presence (social-only, free Wix, GMB-only, parked). Per-record quality score, 50-vertical inference, per-vertical intent signals. URL-pattern classification, no live fetches. For web designers and SEO agencies.",
        "version": "0.1",
        "x-build-id": "D6PE9d6aRY9x9YFfj"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/seibs.co~local-leads-without-websites/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-seibs.co-local-leads-without-websites",
                "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/seibs.co~local-leads-without-websites/runs": {
            "post": {
                "operationId": "runs-sync-seibs.co-local-leads-without-websites",
                "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/seibs.co~local-leads-without-websites/run-sync": {
            "post": {
                "operationId": "run-sync-seibs.co-local-leads-without-websites",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "required": [
                    "locations"
                ],
                "properties": {
                    "mode": {
                        "title": "Mode",
                        "enum": [
                            "all_businesses",
                            "vertical_filter"
                        ],
                        "type": "string",
                        "description": "all_businesses: scrape any business type in the location, then classify by Maps category. vertical_filter: restrict to the verticals you select below.",
                        "default": "all_businesses"
                    },
                    "verticals": {
                        "title": "Verticals (used when mode = vertical_filter)",
                        "maxItems": 50,
                        "uniqueItems": true,
                        "type": "array",
                        "description": "Restrict to these business verticals. Ignored when mode = all_businesses. Leave empty to include every supported vertical.",
                        "items": {
                            "type": "string",
                            "enum": [
                                "restaurants",
                                "cafes",
                                "bars",
                                "retail_clothing",
                                "retail_general",
                                "beauty_salon",
                                "hair_salon",
                                "barber",
                                "nail_salon",
                                "spa",
                                "gym_fitness",
                                "yoga_studio",
                                "dental",
                                "medical_practice",
                                "chiropractor",
                                "veterinarian",
                                "pet_services",
                                "daycare",
                                "auto_repair",
                                "auto_dealer",
                                "home_services_hvac",
                                "home_services_plumbing",
                                "home_services_electrical",
                                "home_services_roofing",
                                "home_services_landscaping",
                                "painter",
                                "contractor_general",
                                "contractor_remodeler",
                                "locksmith",
                                "cleaning_service",
                                "accounting_tax",
                                "law_firm",
                                "real_estate",
                                "insurance",
                                "mortgage",
                                "financial_advisor",
                                "marketing_agency",
                                "photographer",
                                "event_venue",
                                "catering",
                                "florist",
                                "jewelry",
                                "furniture_retail",
                                "bookstore",
                                "music_store",
                                "bakery",
                                "butcher",
                                "liquor_store",
                                "dry_cleaner",
                                "tailor"
                            ]
                        },
                        "default": []
                    },
                    "locations": {
                        "title": "Locations",
                        "minItems": 1,
                        "maxItems": 25,
                        "type": "array",
                        "description": "US locations to search. Accepts city + state (e.g. 'Austin, TX') OR a 5-digit ZIP (e.g. '78701'). Up to 25 locations per run.",
                        "default": [
                            "Austin, TX"
                        ],
                        "items": {
                            "type": "string"
                        }
                    },
                    "radius_miles": {
                        "title": "Radius (miles) per location",
                        "minimum": 5,
                        "maximum": 50,
                        "type": "integer",
                        "description": "Approximate radius (miles) applied to each location. Compass uses this as a soft hint; the actual area depends on Google Maps zoom logic.",
                        "default": 25
                    },
                    "weak_website_filter": {
                        "title": "Weak-website filter",
                        "enum": [
                            "include_weak_websites",
                            "exclude_weak_websites",
                            "only_zero_website"
                        ],
                        "type": "string",
                        "description": "include_weak_websites: emit prospects with no website AND prospects with weak web presence (social-only, free Wix, GMB-only, etc.). This is the broadest pool. exclude_weak_websites: emit ONLY prospects with no website field on the Maps record. only_zero_website: strictest -- exactly the same as exclude_weak_websites today (kept distinct so a future v2 can split parked vs. fully-absent).",
                        "default": "include_weak_websites"
                    },
                    "min_quality_score": {
                        "title": "Minimum quality score (0-1)",
                        "minimum": 0,
                        "maximum": 1,
                        "type": "number",
                        "description": "Filter records below this quality score (0.0 to 1.0). 0.0 emits everything; 0.75 is the 'high-quality' threshold; 0.5 is a good middle ground when you want to skip 5-review, unclaimed listings.",
                        "default": 0
                    },
                    "max_results_per_query": {
                        "title": "Max results per query",
                        "minimum": 1,
                        "maximum": 100,
                        "type": "integer",
                        "description": "Cap on records returned per (search_term x location) tuple. Compass enforces a hard ceiling; we cap at 100 to protect compute budget.",
                        "default": 50
                    },
                    "sort_by": {
                        "title": "Sort order",
                        "enum": [
                            "quality_score_desc",
                            "reviews_count_desc",
                            "rating_desc",
                            "name_asc"
                        ],
                        "type": "string",
                        "description": "Order of the emitted records. quality_score_desc is the recommended default for prospecting.",
                        "default": "quality_score_desc"
                    },
                    "search_terms": {
                        "title": "Search terms (optional override)",
                        "maxItems": 10,
                        "type": "array",
                        "description": "Free-text Google Maps search terms. Combined with each location. If empty, terms are derived from the mode + verticals selection. Example: ['small business', 'local shop'].",
                        "default": [],
                        "items": {
                            "type": "string"
                        }
                    },
                    "exclude_chains": {
                        "title": "Exclude national chains and franchises",
                        "type": "boolean",
                        "description": "When true (default), drops records whose business name matches a national chain or franchise brand (Great Clips, McDonald's, Home Depot, Marriott, etc.). Chains are dropped BEFORE the no-website check, so franchise locations whose Maps listing happens to be missing a website field do NOT leak through. Turn off only if you specifically want chain locations in the output (e.g. you sell to franchisees, not independent businesses). Blocklist covers ~400 common US chains (900+ spelling variants) across fast food, grocery, gas/convenience, big box, auto, hotels, banks, salons, fitness, real estate, etc.",
                        "default": true
                    }
                }
            },
            "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
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
