# BizQuest Business-for-Sale Scraper (`devilscrapes/bizquest-business-for-sale-scraper`) Actor

Scrape BizQuest businesses for sale across the US: title, asking price, city, state, teaser, financing, real-estate and SBA tags, photo and listing URL for the nationwide feed or any state or city, deduplicated.

- **URL**: https://apify.com/devilscrapes/bizquest-business-for-sale-scraper.md
- **Developed by:** [DevilScrapes](https://apify.com/devilscrapes) (community)
- **Categories:** Lead generation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per event

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

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

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

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

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

<p align="center">
  <img src=".actor/icon.svg" width="160" alt="Devil Scrapes mark" />
</p>

## BizQuest Business-for-Sale Scraper

**💰 $6.00 / 1 000 results**  ·  pay only for results  ·  no credit card to try

*The devil's in the data.* 😈

Pull businesses for sale from BizQuest, the US small-business marketplace,
as clean, deduplicated rows: title, asking price, city and state, the
seller's teaser, financing, real-estate and SBA tags, photo, and the
listing URL. Scrape the nationwide feed, a whole state, or a single city.

### 🎯 What this scrapes

BizQuest shows about fifty businesses a page and offers no export. This
Actor walks the listing pages for every route you choose (nationwide, a
state, a city, or a BizQuest URL you paste) and returns one row per
business: listing id, URL, headline, teaser, asking price in USD, city or
county, state code and name, lead photo, and the `Financing Available`,
`Includes Real Estate` and `SBA Loan Eligible` tags. Franchise
advertisements and broker promo cards that BizQuest mixes into its result
list are left out, so every row is a real business for sale.

### 🔥 Features

- 🛡️ **We rotate browser fingerprints** (curl-cffi Chrome, Firefox and
  Safari impersonation) so the site sees a real browser's TLS handshake,
  not a Python script.
- 🔁 **We retry with exponential backoff** on rate limits and server
  errors, honouring `Retry-After`. Up to 5 attempts per page.
- 🌐 **We rotate residential US proxies** through Apify Proxy on every
  block, with a fresh session and exit IP each time.
- 🧊 **Run-wide deduplication.** The same listing id never appears twice
  in your dataset, across pages or across routes in one run.
- 🗺️ **State and city routing.** Type `Texas`, `TX` or `Houston, TX` and
  we build the right BizQuest route for you.
- 🧱 **Fault isolation.** One route that gets blocked doesn't end the
  others; we log it and keep going.
- 💰 **You pay only for results that land.** No data, no charge (only
  the small `actor-start` warm-up fee).

### 💡 Use cases

- **Business brokers and M\&A advisors:** track new listings and asking
  prices by state or metro.
- **Search funds and acquisition entrepreneurs:** build a deal-flow
  pipeline of small businesses with financing or real estate included.
- **Investors and lenders:** watch SBA-eligible listings and asking-price
  trends by region.
- **Market researchers:** measure how many businesses are for sale per
  state and what they ask.

### ⚙️ How to use it

1. Leave `includeNationwide` on for the national feed, add states or
   cities to `locations` (for example `Texas` or `Houston, TX`), or paste
   BizQuest listing URLs into `startUrls`.
2. Set `maxPages` and `maxItems` to bound how much you pull.
3. Run it, then export to JSON, CSV, or Excel, or pull the dataset
   straight from the Apify API.

### 📥 Input

| Field | Type | Required | Default | Notes |
|---|---|---|---|---|
| `includeNationwide` | `boolean` | no | `true` | Scrape the nationwide feed. |
| `locations` | `array<string>` | no | empty | US states (`Texas`, `TX`) or cities (`Houston, TX`). |
| `startUrls` | `array<string>` | no | empty | BizQuest listing-page URLs. A trailing `page-N/` and any query string are ignored. |
| `maxPages` | `integer` | no | `3` | Cap on pages per route, about 50 listings per page (1-200). |
| `maxItems` | `integer` | no | `150` | Hard cap on total rows across the run (1-10000). |
| `proxyConfiguration` | `object` | yes | Residential, US | Apify Proxy configuration. |

#### Example input

```json
{
  "includeNationwide": true,
  "locations": ["Texas"],
  "maxPages": 2,
  "maxItems": 200,
  "proxyConfiguration": { "useApifyProxy": true, "apifyProxyGroups": ["RESIDENTIAL"], "apifyProxyCountry": "US" }
}
```

### 📤 Output

One row per deduplicated business listing.

| Field | Type | Notes |
|---|---|---|
| `listingId` | `string` | BizQuest listing id (BW number), dedupe key. |
| `url` | `string` | Absolute listing URL. |
| `title` | `string` | Listing headline. |
| `description` | `string \| null` | Teaser shown on the card. |
| `askingPrice` | `integer \| null` | Asking price in whole USD, when disclosed. |
| `currency` | `string` | Price currency, `USD`. |
| `locality` | `string \| null` | City or county. |
| `state` / `stateName` | `string \| null` | State code and name. |
| `financialsGated` | `boolean` | BizQuest hides cash flow and EBITDA behind a sign-in. |
| `financingAvailable` | `boolean` | Card carries the Financing Available tag. |
| `includesRealEstate` | `boolean` | Card carries the Includes Real Estate tag. |
| `sbaEligible` | `boolean` | Card carries the SBA Loan Eligible tag. |
| `imageUrl` | `string \| null` | Lead photo URL. |
| `searchRoute` | `string` | Route the row was found on. |
| `pageNumber` / `position` | `integer` | 1-based page and position within the page. |
| `scrapedAt` | `string` | UTC ISO-8601 run timestamp. |

#### Example output record

```json
{
  "listingId": "2540957",
  "url": "https://www.bizquest.com/business-for-sale/private-gym/BW2540957/",
  "title": "Private gym",
  "description": "Members-only fitness club offering 24-hour gym access.",
  "askingPrice": 400000,
  "currency": "USD",
  "locality": "Monument",
  "state": "CO",
  "stateName": "Colorado",
  "financialsGated": true,
  "financingAvailable": false,
  "includesRealEstate": false,
  "sbaEligible": false,
  "imageUrl": "https://images.bizquest.com/shared/listings/254/2540957/117faeb8-bcf4-4de3-aafb-8c8cf5f8c2fe-W336.webp",
  "searchRoute": "/businesses-for-sale/",
  "pageNumber": 1,
  "position": 1,
  "scrapedAt": "2026-10-12T08:00:00Z"
}
```

### 💰 Pricing

Pay-Per-Event: you pay only when these events fire.

| Event | USD | What it is |
|---|---:|---|
| `actor-start` | $0.20 | One-off warm-up charge per run |
| `result-emitted` | $0.006 | Per deduplicated business listing written to the dataset |

Example: 1 000 rows = **$6.20 per run** ($0.20 start + 1000 x $0.006).
No subscription, no minimum, no card required to try it.

### 🚧 Limitations

- **Search-card fields only.** This returns what the listing results
  publish. Full listing detail pages, broker contact details and the
  confidential financials are out of scope.
- **Cash flow, EBITDA and revenue are not returned.** BizQuest shows them
  only to signed-in visitors, so the Actor flags those listings with
  `financialsGated` instead of guessing.
- **Asking price can be empty.** Listings that do not disclose a price
  come back with `askingPrice` set to `null`.
- **Result depth.** BizQuest serves up to about 200 pages for the
  nationwide feed; set `maxPages` high enough for the depth you need.
- **URL filters are not applied.** Paste the route you want (nationwide,
  state or city); query-string filters on a pasted URL are dropped.
- **A route with no listings is a success.** It finishes with zero rows
  and a status message naming what was scraped.

### ❓ FAQ

**Do I need a BizQuest account or API key?**
No. This reads BizQuest's public listing pages.

**How do I scrape one state or city?**
Add it to `locations`: `Texas`, `TX`, or `Houston, TX`. Turn off
`includeNationwide` if you want only those routes.

**Why did my run return fewer rows than `maxItems`?**
Either the route has fewer listings than your cap, or `maxPages` stopped
the run first. The status message tells you which.

**Why are franchise results missing?**
BizQuest mixes franchise advertisements into its listing pages. Those are
not businesses for sale, so we leave them out.

**What happens if a page is blocked?**
We retry up to 5 times with a fresh browser fingerprint and proxy
session each time. If a route still can't be read, the others carry on
and the status message says so. The run ends as failed only when a route
was blocked and nothing at all could be collected.

**Can I run this on a schedule?**
Yes. Use Apify Schedules to re-run your routes daily or weekly and catch
newly listed businesses.

### 💬 Your feedback

Found a bug, or need a field we don't return yet? Open an issue on the
Actor's Issues tab. We read every one.

# Changelog

This Actor's version history is a separate document: https://apify.com/devilscrapes/bizquest-business-for-sale-scraper/changelog.md

# Actor input Schema

## `includeNationwide` (type: `boolean`):

Scrape the nationwide BizQuest businesses-for-sale feed. Turn off to scrape only the states, cities and URLs below.

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

US states ('Texas' or 'TX') or cities ('Houston, TX'). Each location becomes its own listing route.

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

Optional BizQuest listing-page URLs, for example https://www.bizquest.com/businesses-for-sale-in-florida-fl/. A trailing page-N/ is ignored; we page for you.

## `maxPages` (type: `integer`):

Cap on result pages fetched per route (about 50 listings per page).

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

Hard cap on total deduplicated listings emitted across the whole run.

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

Apify Proxy configuration. Residential with a US exit is the default for reliable results.

## Actor input object example

```json
{
  "includeNationwide": true,
  "locations": [
    "Texas"
  ],
  "startUrls": [],
  "maxPages": 2,
  "maxItems": 200,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "US"
  }
}
```

# Actor output Schema

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

All dataset items as JSON.

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

Same data exported to CSV.

## `datasetView` (type: `string`):

Open the run dataset in the Console.

# 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 = {
    "includeNationwide": true,
    "locations": [
        "Texas"
    ],
    "maxPages": 2,
    "maxItems": 200,
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ],
        "apifyProxyCountry": "US"
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("devilscrapes/bizquest-business-for-sale-scraper").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 = {
    "includeNationwide": True,
    "locations": ["Texas"],
    "maxPages": 2,
    "maxItems": 200,
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
        "apifyProxyCountry": "US",
    },
}

# Run the Actor and wait for it to finish
run = client.actor("devilscrapes/bizquest-business-for-sale-scraper").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 '{
  "includeNationwide": true,
  "locations": [
    "Texas"
  ],
  "maxPages": 2,
  "maxItems": 200,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "US"
  }
}' |
apify call devilscrapes/bizquest-business-for-sale-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,devilscrapes/bizquest-business-for-sale-scraper"
        }
    }
}
```

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/6W23kNuwPW75mGvXo/builds/SBllomwzY3gm65Ho5/openapi.json
