# Multi-Source Business Verification (`enc_motion_outdoor/multi-source-business-verification`) Actor

Confirms qualified business leads using ordinary Google Search, with optional Yelp and BBB evidence.

- **URL**: https://apify.com/enc\_motion\_outdoor/multi-source-business-verification.md
- **Developed by:** [J.R. Moore](https://apify.com/enc_motion_outdoor) (community)
- **Categories:** Lead generation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.00 / 1,000 google business checks

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — 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

## Multi-Source Business Verification

Brand Verification is an optional website module. It reuses the staged website crawl, returns confirmed and possible brands with evidence URLs, and can remain limited to the product categories selected by the user.

An independent Apify Actor that verifies already-qualified business leads through Google business evidence and optional refinement sources.

### Best-in-class verification foundation

The first approved upgrade phase is active:

- A versioned Actor registry separates production sources from controlled pilot candidates.
- Every source record follows a common evidence contract with its Actor, schema versions, evidence URLs, collection date, and expiration date.
- Checkpoints are exact to the Apify tenant, business identity, source, selected product scope, source-data version, and analysis version.
- Legacy checkpoints are reused when still valid and automatically migrated to the new key without repeating the downstream check.
- Pre-run and final estimates separate new checks, reusable checks, downstream Actor expense, Furniture Retail Intelligence fees, and the maximum expected total.
- Shared Supabase tables persist the registry, exact source checkpoints, and cost estimates for multi-user continuation.

Pilot Actors are cataloged but are not promoted into the production path until controlled comparisons pass.

- Google confirmation and Google rating/review count are the default.
- Yelp and BBB are optional source checks.
- It does not use Google Maps for discovery; it only confirms leads already returned by Overture.
- Google product evidence runs first. Only unresolved selected product groups are sent to the dedicated staged Website Evidence Actor.
- Website evidence reuses category checkpoints, tries inexpensive HTTP first, renders a browser only when needed, and can optionally use a residential retry.
- A blocked website is reported as unable to verify, never as proof that the product is absent.
- Facebook remains a fallback when prior evidence does not confirm the requested products.
- Every business/source pair is checkpointed to avoid paying for a fresh check twice.
- Google Business checkpoints are reusable across later product-category selections and analysis-library updates until they expire. Website and Facebook checkpoints remain product-category-specific.
- `maximumSourceChecks` is the per-run paid-search guard.

### Cost behavior

Google and optional review lookups use their configured downstream source. Website use is bounded by selected leads, selected product groups, and one to five targeted pages per website. Residential proxy use is off by default. A transient search timeout is retried once by default; the run hard cap remains the final spending limit for charge-capped downstream Actors.

Creator pricing standard `2026-08-02.1`:

| Completed new event | Creator fee |
| --- | ---: |
| Google business check | $0.003 per business |
| Website refinement check | $0.003 per business |
| Facebook fallback check | $0.003 per business |
| Yelp, BBB, Houzz, or Trustpilot check | $0.003 per source/business |
| Company registry check | $0.003 per business |
| Product-category analysis | $0.001 per business/category |
| Brand Verification bundled with another website module | $0.003 per business |
| Standalone Brand Verification, including its website visit | $0.005 per business |

Overture discovery, downloads, failed work, and current reusable checkpoints have no creator fee. Downstream Actor, proxy, and platform usage is separate and is shown before a run. Creator charging requires both the run request and the owner-controlled `FRI_CREATOR_BILLING_ENABLED=true` environment switch. Keep that switch off until these exact events are configured in Apify pay-per-event monetization.

During the beta phase, creator billing stays off. Each run still publishes `creatorChargePreview` and `projectedCreatorFeeUsd` so observed costs can be compared with this standard before public charging is enabled.

### Matching policy

The Actor compares the lead name and location with search evidence. Strong name and location agreement is confirmed. Ambiguous evidence is marked for review instead of being silently accepted.

This Actor is designed as a verification stage. It does not decide whether a business fits a selected furniture category.

### Gold-standard benchmark gate

No pilot Actor becomes a production source based only on a successful run. The Phase 2 benchmark compares it with the current route using a human-reviewed United States and Canada case set. Promotion requires at least 92% precision, 85% recall, no more than a 5% false-positive rate, 95% evidence completeness, balanced country coverage, no precision regression, and a controlled cost ratio. The template is in `benchmarks/gold-standard-template.json`; `scripts/evaluate-benchmark.mjs` produces the promotion report.

# Actor input Schema

## `leads` (type: `array`):

Lead objects passed directly from a discovery workflow.

## `reviewSources` (type: `array`):

Choose Google identity verification, website with Facebook fallback, or optional review sources.

## `productCategories` (type: `array`):

Website and Facebook evidence is evaluated only for these requested product categories.

## `verificationModules` (type: `array`):

Records which optional analyses were requested so completed checks can be reused safely.

## `analysisVersion` (type: `string`):

Invalidates older checkpoints when lead scoring or evidence rules change.

## `googleMapsActorId` (type: `string`):

Downstream actor used for Google business-profile categories, ratings, and identity evidence.

## `googleSearchActorId` (type: `string`):

Official Google Search Actor used for profile discovery, Facebook fallback discovery, and optional rating sources.

## `googleSearchRuntimeMode` (type: `string`):

Uses the official Actor by default and keeps the internal crawler as an automatic operational fallback.

## `googleSearchHardCapUsd` (type: `number`):

Maximum charge guard for the single batched Google Search evidence run.

## `googleMapsHardCapUsd` (type: `number`):

Portion of the combined run cap reserved for Google Maps verification.

## `facebookPagesActorId` (type: `string`):

Dedicated page actor used only after Google Search finds and identity-matches a Facebook page.

## `facebookDeepEvidence` (type: `boolean`):

When Facebook verification is selected, inspect the matched page for categories, contact details, recommendations, and product evidence.

## `facebookPagesHardCapUsd` (type: `number`):

Maximum charge guard for the batched second-stage Facebook page run.

## `parentHardCapUsd` (type: `number`):

Portion of the combined run cap reserved for this orchestration actor.

## `combinedHardCapUsd` (type: `number`):

User-approved maximum for the complete verification workflow, including the parent and downstream Actors.

## `hardCapPlanVersion` (type: `string`):

Internal version label for the workflow's combined-cap allocation rules.

## `maximumLeads` (type: `integer`):

Maximum businesses considered in this run.

## `maximumSourceChecks` (type: `integer`):

Hard stop on new source checks across all optional modules.

## `acceptedLeadStatuses` (type: `array`):

Only leads with these discovery statuses are eligible. Leads without a status remain eligible for direct testing.

## `onlyUnverified` (type: `boolean`):

Prevents repeat search charges while a saved source check is still fresh.

## `freshnessDays` (type: `integer`):

A completed source check is reused for this many days.

## `sourceFreshnessDays` (type: `object`):

Optional days-to-reuse by source, for example {"google":30,"website":30,"facebook":14}. Unlisted sources use the versioned Actor registry default.

## `tenantKey` (type: `string`):

Separates checkpoints for different customers or workspaces.

## `registryStoreName` (type: `string`):

Persistent storage used to prevent duplicate source checks.

## `seededCheckpoints` (type: `array`):

Internal evidence checkpoints supplied by the Furniture Retail Intelligence workflow to prevent duplicate paid checks.

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

Higher values finish faster; lower values are gentler and easier to monitor.

## `websiteConcurrency` (type: `integer`):

A conservative limit protects memory and avoids overwhelming retailer websites.

## `websiteEvidenceActorId` (type: `string`):

Dedicated staged Actor used for cached HTTP, browser, and optional residential website evidence.

## `brandScope` (type: `string`):

Limit brands to selected product categories or return all supported brands found.

## `enableBrandVerificationBilling` (type: `boolean`):

Internal request flag. Charges remain disabled unless the Actor owner also enables the protected environment switch after Apify prices are configured.

## `enableCreatorBilling` (type: `boolean`):

Internal request flag. Charges remain disabled unless the Actor owner also enables the protected environment switch after every event price is configured in Apify.

## `websiteEvidenceHardCapUsd` (type: `number`):

Maximum charge guard passed to the website Actor; lead and page limits also bound compute use.

## `websiteMaxPages` (type: `integer`):

Maximum targeted pages checked per business, including the home page.

## `websiteBrowserFallback` (type: `boolean`):

Render JavaScript-heavy or inconclusive sites in a browser after the inexpensive request.

## `websiteResidentialRetry` (type: `boolean`):

Optional paid last retry for a site still blocked after normal browser rendering.

## `maxRetriesPerSource` (type: `integer`):

Retries one transient timeout or network failure before marking the source incomplete. Set to zero for the strictest cost behavior.

## Actor input object example

```json
{
  "leads": [],
  "reviewSources": [
    "google"
  ],
  "productCategories": [],
  "verificationModules": [],
  "analysisVersion": "2026-08-05.1",
  "googleMapsActorId": "compass/crawler-google-places",
  "googleSearchActorId": "apify/google-search-scraper",
  "googleSearchRuntimeMode": "official_actor",
  "googleSearchHardCapUsd": 0.5,
  "googleMapsHardCapUsd": 0.5,
  "facebookPagesActorId": "apify/facebook-pages-scraper",
  "facebookDeepEvidence": true,
  "facebookPagesHardCapUsd": 0.25,
  "parentHardCapUsd": 0.5,
  "maximumLeads": 100,
  "maximumSourceChecks": 100,
  "acceptedLeadStatuses": [
    "good_lead_candidate",
    "plausible_needs_verification"
  ],
  "onlyUnverified": true,
  "freshnessDays": 30,
  "sourceFreshnessDays": {},
  "tenantKey": "default",
  "registryStoreName": "multi-source-business-verification-registry",
  "seededCheckpoints": [],
  "maxConcurrency": 3,
  "websiteConcurrency": 2,
  "websiteEvidenceActorId": "MJkf4SeVEdE49Lxde",
  "brandScope": "selected_categories",
  "enableBrandVerificationBilling": false,
  "enableCreatorBilling": false,
  "websiteEvidenceHardCapUsd": 0.5,
  "websiteMaxPages": 3,
  "websiteBrowserFallback": true,
  "websiteResidentialRetry": false,
  "maxRetriesPerSource": 1
}
```

# Actor output Schema

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

No description

## `dataset` (type: `string`):

No description

# 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 = {};

// Run the Actor and wait for it to finish
const run = await client.actor("enc_motion_outdoor/multi-source-business-verification").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 = {}

# Run the Actor and wait for it to finish
run = client.actor("enc_motion_outdoor/multi-source-business-verification").call(run_input=run_input)

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

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

```

## CLI example

```bash
echo '{}' |
apify call enc_motion_outdoor/multi-source-business-verification --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,enc_motion_outdoor/multi-source-business-verification"
        }
    }
}

```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/7wORUjOB49Je5FmjR/builds/gdrqFlxwdsTNgqAaa/openapi.json
