# BizBuySell Deal Monitor & Price Drop Alerts (`fetchfinch/bizbuysell-deal-monitor`) Actor

Monitor business-for-sale listings for new deals, asking-price changes, financial updates, and listings that leave a tracked search.

- **URL**: https://apify.com/fetchfinch/bizbuysell-deal-monitor.md
- **Developed by:** [Fetch Finch](https://apify.com/fetchfinch) (community)
- **Categories:** Lead generation, Automation, Integrations
- **Stats:** 2 total users, 1 monthly users, 95.8% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $20.00 / 1,000 monitor runs

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.

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

## BizBuySell Deal Monitor & Price Drop Alerts

Find business-acquisition opportunities and see what changed since your last BizBuySell search.

This unofficial monitor turns a recurring BizBuySell search into a persistent alert feed. It detects new listings, asking-price changes, newly disclosed financials, and other listing updates, then returns structured JSON that can be sent to a spreadsheet, CRM, Slack, webhook, or data warehouse.

> This Actor is not affiliated with, sponsored by, or endorsed by BizBuySell. It uses publicly available listing data, which may be incomplete, delayed, changed, or temporarily unavailable.

### Try a ready-made example

[California BizBuySell Deal Alerts](https://apify.com/fetchfinch/bizbuysell-deal-monitor/examples/california-acquisitions-demo)

The example watches one California search, excludes franchises, enriches listing details, and emits new-listing and change events.

### Quick start

1. Enter one BizBuySell search URL.
2. Choose a stable, unique `monitorKey` (for example, `california-hvac`).
3. Run the Actor once, then schedule it daily or weekly with the same configuration.
4. Use the dataset output or connect the run to your automation tool.

Example input:

```json
{
  "startUrls": [
    { "url": "https://www.bizbuysell.com/california-businesses-for-sale/" }
  ],
  "monitorKey": "california-acquisitions",
  "maxItems": 25,
  "maxPagesPerUrl": 1,
  "enrichDetails": true,
  "excludeFranchises": true,
  "firstRunBehavior": "emit_all_as_new",
  "eventTypes": [
    "NEW_LISTING",
    "PRICE_DROP",
    "PRICE_INCREASE",
    "FINANCIALS_CHANGED",
    "LISTING_UPDATED"
  ],
  "sourceMaxTotalChargeUsd": 1
}
```

Use a different `monitorKey` for each state, geography, or materially different filter set. Do not run the same key concurrently.

### What the Actor detects

| Event | Meaning |
|---|---|
| `NEW_LISTING` | The listing was not in this monitor's saved history. |
| `PRICE_DROP` / `PRICE_INCREASE` | The numeric asking price changed. |
| `FINANCIALS_CHANGED` | Cash flow, revenue, or EBITDA changed or was newly disclosed. |
| `LISTING_UPDATED` | Another tracked public field changed. |
| `NO_LONGER_IN_RESULTS` | The listing was absent for the configured number of snapshots. This is not proof that it sold. |
| `UNCHANGED` | Optional output for listings with no detected change. |

The first run can either emit current listings as `NEW_LISTING` events or quietly save a baseline with `firstRunBehavior: "baseline_only"`. Later runs emit only selected event types. `detectMissing` is off by default because partial or re-sorted result windows can create false disappearance alerts.

### Input options

| Input | Purpose |
|---|---|
| `startUrls` | One BizBuySell state or national search URL. |
| `monitorKey` | Persistent history key; keep it unchanged between scheduled runs. |
| `maxItems`, `maxPagesPerUrl` | Control snapshot size, depth, runtime, and source cost. |
| `enrichDetails` | Collect seller-disclosed financials, rent, inventory, employees, and other detail fields. |
| `includeBrokerContacts` | Include publicly displayed broker fields when enrichment is enabled. |
| `minAskingPrice`, `maxAskingPrice` | Apply an asking-price range. |
| `includeKeywords`, `excludeKeywords` | Match terms against title, description, and location. |
| `minDealScore`, `minScoreConfidence` | Emit only listings meeting a transparent screening threshold and evidence level. |
| `excludeFranchises` | Exclude franchise opportunities; enabled by default. |
| `firstRunBehavior` | Emit the first snapshot or save it as a quiet baseline. |
| `eventTypes`, `minPriceDropPercent` | Choose event types and suppress small price drops. |
| `emitUnchanged` | Include unchanged listings in the output. Off by default. |
| `detectMissing`, `missingAfterRuns` | Opt in to consecutive-miss alerts for stable, complete searches. |
| `sourceMaxTotalChargeUsd` | Maximum charge allowed for the upstream extraction run. |

Advanced replay/testing inputs include `sourceDatasetId`, which reads an existing Apify dataset instead of calling the default source. `resetState`, `allowEmptySnapshot`, and `includeRawSource` should normally remain off.

### Output

Each emitted item includes the event, listing identity, title, URL, location, asking price, source timestamps, and change details. When available it also includes cash flow, gross revenue, EBITDA, inventory, rent, employees, broker fields, `dealScore`, and `scoreConfidence`.

Example:

```json
{
  "eventType": "PRICE_DROP",
  "monitorKey": "california-acquisitions",
  "listingId": "2508641",
  "title": "Profitable HVAC Company with Seller Financing",
  "url": "https://www.bizbuysell.com/business-opportunity/profitable-hvac-company/2508641/",
  "askingPriceNumeric": 675000,
  "previousAskingPriceNumeric": 750000,
  "priceChangePercent": -10,
  "cashFlowNumeric": 300000,
  "dealScore": 86,
  "scoreConfidence": 100,
  "changes": [
    {
      "field": "askingPriceNumeric",
      "previous": 750000,
      "current": 675000,
      "percentChange": -10
    }
  ]
}
```

The `OUTPUT` key in the run's default key-value store contains a summary with source counts, rejected records, event counts, and saved-state counts. Source Actor/run/build/dataset identifiers and a source-schema fingerprint are included for provenance.

### Deal score

`dealScore` is a transparent 0–100 screening heuristic based only on seller-disclosed data. It considers asking-price-to-cash-flow, asking-price-to-revenue, cash-flow margin, and visible seller-financing or real-estate signals. `scoreConfidence` shows how much evidence was available. Missing financial data is never invented, and the score is not a valuation, lending decision, or due-diligence substitute.

### Pricing

The Actor uses pay-per-event pricing:

- **Monitor run:** `$0.02` per snapshot
- **Change event:** `$0.005` per emitted event

Apify platform usage and the upstream extraction service may add costs depending on the selected pricing configuration and snapshot size. Set a maximum cost per run and use `maxItems`/`maxPagesPerUrl` to control spend.

### Reliability and limitations

- Saved history is retained across scheduled runs for each `monitorKey`.
- Empty or materially invalid source snapshots fail safely without overwriting good state.
- Duplicate source records are collapsed by listing ID.
- Temporary enrichment gaps preserve the last known value and identify it in `preservedFields`.
- Source availability depends on BizBuySell and the configured upstream extractor; there is no source SLA.
- Seller-provided financials may be incomplete, stale, rounded, or unaudited.
- A listing leaving the search results does not prove that it sold.
- Review BizBuySell's current terms, robots guidance, and applicable privacy, copyright, and anti-spam rules before use.

### Integrations

Use Apify schedules, webhooks, Make, Zapier, n8n, Slack, email, Google Sheets, Airtable, or a CRM to consume the dataset and event feed. Use `listingId` as the stable upsert key.

# Actor input Schema

## `startUrls` (type: `array`):

National or US-state BizBuySell businesses-for-sale pages. Keep these stable between runs of the same monitor.

## `monitorKey` (type: `string`):

Stable name for this watchlist and its saved history, for example california-car-washes. Use a different name for every distinct search configuration.

## `maxItems` (type: `integer`):

Maximum unique listings collected across the searches on each run.

## `maxPagesPerUrl` (type: `integer`):

Controls search depth and upstream extraction cost.

## `enrichDetails` (type: `boolean`):

Visit listing pages for cash flow, gross revenue, EBITDA, real estate, inventory, and other disclosed details. Recommended for deal scoring.

## `includeBrokerContacts` (type: `boolean`):

Collect broker fields when publicly displayed. Requires financial-detail enrichment.

## `minAskingPrice` (type: `integer`):

Exclude listings with a disclosed asking price below this amount.

## `maxAskingPrice` (type: `integer`):

Exclude listings with a disclosed asking price above this amount.

## `includeKeywords` (type: `array`):

Case-insensitive terms checked against title, description, and location. Leave empty to include every listing.

## `excludeKeywords` (type: `array`):

A listing containing any term in its title, description, or location is left out of this monitor.

## `minDealScore` (type: `integer`):

Only output events whose transparent screening score meets this threshold. State is still updated for lower-scoring listings.

## `minScoreConfidence` (type: `integer`):

When a minimum deal score is active, require this percentage of the scoring evidence to be available. The default prevents revenue-only scores from passing a score filter.

## `excludeFranchises` (type: `boolean`):

Exclude franchise opportunities that can appear in state search results alongside existing businesses for sale.

## `firstRunBehavior` (type: `string`):

Emit the initial snapshot as NEW\_LISTING events, or save a quiet baseline for later comparisons.

## `eventTypes` (type: `array`):

The monitor always tracks every detected change, but only selected event types are written to the dataset.

## `minPriceDropPercent` (type: `number`):

Suppress smaller PRICE\_DROP events. Other event types are unaffected.

## `emitUnchanged` (type: `boolean`):

Useful for full snapshot exports, but normally disabled for alert workflows.

## `detectMissing` (type: `boolean`):

Emit NO\_LONGER\_IN\_RESULTS after consecutive misses. Keep disabled for partial or frequently re-sorted searches to avoid false alerts.

## `missingAfterRuns` (type: `integer`):

Require this many consecutive snapshots without a listing before emitting NO\_LONGER\_IN\_RESULTS.

## `resetState` (type: `boolean`):

Deletes the saved snapshot for this monitor key, then treats the run as a new baseline.

## `allowEmptySnapshot` (type: `boolean`):

Disabled by default to protect saved state when the source unexpectedly returns no listings.

## `sourceActorId` (type: `string`):

Advanced dependency override. The default is a low-cost public BizBuySell extraction Actor.

## `sourceDatasetId` (type: `string`):

Optional dataset ID for replay, testing, or custom extraction. When set, the raw listing Actor is not called.

## `sourceMaxTotalChargeUsd` (type: `number`):

Hard spending limit passed to the upstream pay-per-event Actor. Ignored when replaying an existing dataset.

## `proxyConfiguration` (type: `object`):

Passed to the raw extraction Actor when provided.

## `includeRawSource` (type: `boolean`):

Adds the unnormalized source record to each event. This can substantially increase dataset size.

## Actor input object example

```json
{
  "startUrls": [
    {
      "url": "https://www.bizbuysell.com/california-businesses-for-sale/"
    }
  ],
  "monitorKey": "california-acquisitions",
  "maxItems": 20,
  "maxPagesPerUrl": 1,
  "enrichDetails": true,
  "includeBrokerContacts": false,
  "minDealScore": 0,
  "minScoreConfidence": 50,
  "excludeFranchises": true,
  "firstRunBehavior": "emit_all_as_new",
  "eventTypes": [
    "NEW_LISTING",
    "PRICE_DROP",
    "PRICE_INCREASE",
    "FINANCIALS_CHANGED",
    "LISTING_UPDATED",
    "NO_LONGER_IN_RESULTS"
  ],
  "minPriceDropPercent": 0,
  "emitUnchanged": false,
  "detectMissing": false,
  "missingAfterRuns": 2,
  "resetState": false,
  "allowEmptySnapshot": false,
  "sourceActorId": "automation-lab/bizbuysell-business-listings-scraper",
  "sourceMaxTotalChargeUsd": 1,
  "includeRawSource": false
}
```

# 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 = {
    "startUrls": [
        {
            "url": "https://www.bizbuysell.com/california-businesses-for-sale/"
        }
    ],
    "monitorKey": "california-acquisitions",
    "maxItems": 20,
    "maxPagesPerUrl": 1
};

// Run the Actor and wait for it to finish
const run = await client.actor("fetchfinch/bizbuysell-deal-monitor").call(input);

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

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

```

## Python example

```python
from apify_client import ApifyClient

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

# Prepare the Actor input
run_input = {
    "startUrls": [{ "url": "https://www.bizbuysell.com/california-businesses-for-sale/" }],
    "monitorKey": "california-acquisitions",
    "maxItems": 20,
    "maxPagesPerUrl": 1,
}

# Run the Actor and wait for it to finish
run = client.actor("fetchfinch/bizbuysell-deal-monitor").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 '{
  "startUrls": [
    {
      "url": "https://www.bizbuysell.com/california-businesses-for-sale/"
    }
  ],
  "monitorKey": "california-acquisitions",
  "maxItems": 20,
  "maxPagesPerUrl": 1
}' |
apify call fetchfinch/bizbuysell-deal-monitor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,fetchfinch/bizbuysell-deal-monitor"
        }
    }
}

```

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/GT7xfL8JAAbACYGTP/builds/VargLk1ol7eAG8ymA/openapi.json
