# Businesses for Sale Leads: Listings + Broker Contacts (`buff_pineapple/businesses-for-sale-leads`) Actor

Businesses listed for sale across Transworld, BizBen, BusinessesForSale.com and Empire Flippers: asking price, cash flow, revenue, location and the broker's public phone and email. Filter by state, category and price; schedule it for daily new-listing alerts.

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

## Pricing

from $1.00 / 1,000 business listing delivereds

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

### What it does

Businesses for Sale Leads reads public business-for-sale marketplaces and returns one row per business listed for sale. Each row has the asking price, cash flow (SDE), revenue, inventory and equipment value where the listing page prints them, the year established, employees, location, category, the listing link and who is selling it (a broker or the owner). When the listing page names a broker (or, on BizBen, the owner) and shows a phone number or email as plain text, you get those too, and BizBen also gives you the date a listing was really posted. You choose the marketplaces, the state or city, the kind of business and a price band. You can also schedule it daily and receive only listings you have not been sent before, which turns it into a deal-flow alert.

The pitch in one sentence: fresh listings, with the person to call when the marketplace publishes that person.

#### Who it is for

- Business brokers who want to see other brokers' listings and find sellers to prospect.
- SBA lenders and loan brokers who want a steady list of businesses on the market in their region, with price and cash flow.
- Search-fund and ETA buyers, and private-equity roll-up teams, who screen for price, cash flow and category.
- Franchisors and vendors that sell around a change of ownership (payroll, insurance, POS, accounting): a listing is a business about to change hands.
- Researchers and analysts who track asking prices and multiples of small businesses.

### Sources covered

| Marketplace | Listings (when measured) | What you get | Broker contact |
|---|---|---|---|
| Transworld Business Advisors (tworld.com) | about 3,500 (3,519 on 2026-10-23) | Price, cash flow, revenue, inventory, equipment, employees, year, reason for selling, description | Advisor name, phone and email, plain text on the page |
| BusinessesForSale.com US (us.businessesforsale.com) | about 17,700 (17,773 on 2026-10-23) | Price, revenue, cash flow, inventory and equipment, employees, year established, reason for selling, real estate | Broker name only, and only on broker-listed ads. No phone and no email: the site shows a contact form. Owner-listed ads are anonymous |
| Empire Flippers (api.empireflippers.com) | 170 online businesses (170 for sale on 2026-10-23, 74 of the first 100 in the US) | Price, revenue, profit, niche, reason for sale, true listing and update dates | None. The row names Empire Flippers as the brokerage and no person |
| BizBen (bizben.com) | about 6,900 listing links in its sitemap on 2026-10-23: 3,616 are BizBen's own, 3,214 are republished from Transworld and 45 from Flippa. California alone has about 3,080 listings, Texas about 450 | Price (or "Call/Email" when the seller hides it), revenue, cash flow, equipment value (FF\&E) where the page prints it, year established, employees, reason for selling, category, location, description, the real posting date and BizBen's own update timestamp (refreshed in bulk for promoted listings, so not an edit date). For copies of Transworld listings the page's "Other Information" lines (sales, seller's discretionary earnings, inventory) are delivered as revenue, cash flow and inventory even when the price box says "Call/Email" | Broker or owner name, phone and email as plain text on the page, for broker-listed and owner-listed ads |

Empire Flippers lists online businesses without a state or city, so it only contributes to searches for "United States" and is skipped for a state or city search (the run status says so).

BizBen shows when a listing was posted (Empire Flippers does show true dates too; Transworld and BusinessesForSale.com do not). About half of its listings are Transworld listings that BizBen republishes (their id starts with `tw:`). When Transworld is also one of the selected marketplaces they are skipped on BizBen, because Transworld is read directly and you would otherwise pay twice for the same business; when Transworld is not selected they are delivered with the quality flag `syndicated_from_transworld`. BizBen also republishes Flippa listings: those are never read (see the legal note). BizBen hides the city of many listings (about half of the listings on the Texas pages we looked at show only the county or the state), so a city search finds only the listings that show their city. A US-wide BizBen search reads the state pages (about 51 requests, one per state, before any listing page), takes the newest postings of the whole country first and works out a date window such as "posted within 7 days" from each listing's own posting date. BizBen's sitemap is only used when it is current (its newest own listing at most two days old); when we read it from Apify it was weeks out of date, so expect the state pages. A BizBen-only nationwide run therefore delivers mostly Transworld listings that BizBen republishes (flagged `syndicated_from_transworld`) unless Transworld is also selected, in which case those come from Transworld.

### Sources not covered, and why

- **BizBuySell, BizQuest and LoopNet** (CoStar) refuse automated access. Our test requests to them returned access-denied pages. The actor does not read them: a blocked request is retried only through fresh Apify datacenter proxy sessions (see the Proxy input), and a challenge page or CAPTCHA is never solved. These are the largest US marketplaces, so coverage here is partial: this actor does not list all US businesses for sale and you should not treat it as if it did.
- **Flippa, Website Closers and DealStream** are left out because their terms of use restrict robots, data mining or automated collection (DealStream: personal, non-commercial use). We did not want to build on pages whose terms say no, and the Flippa listings that BizBen republishes are not read either. This is our product choice, not legal advice. BizBen's own terms also restrict automated access; read the legal note below to see why it is covered anyway.
- A number of other brokerage sites (Sunbeltnetwork, BusinessMart, BusinessBroker.net and others) answer with a bot challenge or a block and are not covered either.

Terms position of the four sources that are covered, in plain words: Transworld has no terms-of-use page that we could find, and its robots.txt asks for one request every 10 seconds (the actor follows that). We read that as "nothing found", not as permission. BusinessesForSale.com's terms have no clause against automated reading that we found, but say the data is owned by or licensed to the site operator, and its robots.txt disallows the query-style search pages (the actor only reads the path-style pages). The actor follows the site's redirect for robots.txt and uses the live robots file. Empire Flippers' terms have no scraping clause that we found and its API robots.txt is empty. BizBen's terms of use forbid robots and data mining (see the legal note): its robots.txt allows the pages the actor reads, and the actor never requests the `?offset=` or `?orderby=` address forms that robots.txt disallows. You are responsible for how you use the data.

### The contact-honesty rule

The actor delivers a phone number or an email only when it is plain text on the public page. If a contact is shown only as an image, hidden behind a "reveal" button, obfuscated, or available only through a contact form, the field is `null`. Nothing is guessed, derived from the broker's name, or taken from another site. The actor never logs in, never submits a form and never clicks a reveal control.

Every row tells you which case it is in `broker.contact_basis`:

- `plain_text`: a phone or an email (or both) was shown as text on the page.
- `none`: the page shows no public phone or email.
- `skipped_budget`: a contact existed but was withheld because your maximum cost per run was reached.

BizBen prints the contact in the listing text ("please contact ... at ... or ...") and in the page data. The actor delivers a BizBen phone or email only when it is in the page data AND printed in the page text; a value that is in the data but not printed is withheld and the row gets the flag `contact_not_in_page_text`. A phone the broker typed with a trailing word ("510-500-7975 call") is delivered as the number only. BizBen phone numbers with 10 digits (a leading country code 1 is dropped) are returned in one form, `(510) 500-7975`, with an extension kept as printed; any other number is returned exactly as printed, and digits are never changed. For an owner-listed BizBen ad (`seller_type` owner) the contact is the seller's own name, phone and email as the seller published them. There is no separate seller field, so they are returned in the `broker` object with the brokerage left empty, and they count as a broker contact for billing.

In practice that means Transworld and BizBen rows carry a phone or an email, while BusinessesForSale.com rows usually carry no contact at all. BizBen rows copied from Transworld carry the advisor's email but no phone.

### Inputs

Everything has a default, so you can start a run from the pre-filled form.

| Input | Default | What it does |
|---|---|---|
| Marketplaces (`sources`) | all four | `transworld`, `businessesforsale`, `empireflippers`, `bizben`. An empty list reads ALL marketplaces and the run says so in its log and status. To read fewer, list only the ones you want. The requested results are shared fairly between marketplaces. |
| Categories (`categories`) | none | Presets mapped to each marketplace (restaurants, food, retail, services, manufacturing, online, healthcare, construction, automotive, franchises, transportation, wholesale, professional-services, beauty-fitness, education-childcare, technology, leisure-hospitality) or any free text matched against category and title. |
| Keywords (`keywords`) | none | A listing matches when its title, category or description contains any of these words. |
| Locations (`locations`) | United States | US state names or codes (Florida, TX), "City, ST" (Miami, FL) or "United States". A listing matches any of them. A place the actor does not recognise is ignored with a warning when another location is valid; the run fails with a clear message, before reading any marketplace, only when NO location is recognised. No listing or contact is charged for such a run, but the memory-scaled actor-start event still is. |
| Minimum / maximum asking price (`minPrice`, `maxPrice`) | none | USD. Listings with no disclosed price are left out when either is set; a price range counts when it overlaps your band. |
| Minimum cash flow (`minCashFlow`) | none | USD. Listings that show no cash flow are left out. |
| Minimum revenue (`minRevenue`) | none | USD. Listings that show no revenue are left out. |
| Posted or updated within days (`postedWithinDays`) | none | Uses the date the marketplace shows (BizBen: the real posting date, so the window is exact; Empire Flippers: listing date; BusinessesForSale.com: last-modified date from its sitemap). Transworld shows no date, so its rows are kept and flagged `date_unknown`. |
| Listed by (`sellerType`) | any | `any`, `broker` or `owner`. Transworld and Empire Flippers are always brokers, so `owner` skips them. On BizBen a listing that carries the seller's own "For Sale By Owner" tag is `owner`; otherwise the account type in the page data decides (broker or owner), and where it is neither (type "other", "non-broker" or missing) the row is `unknown` and is left out when you choose broker or owner. With `includeDetails` off, BizBen is not read at all when you choose broker or owner, because only the listing page says which it is. |
| Read each listing page (`includeDetails`) | on | On: the listing page is read for the description, inventory and equipment value (only where the page prints a value), employees, year, reason for selling and broker. Off: list-page data only, faster. Transworld with this off has no revenue, description or broker contact; BizBen with this off has price, revenue, cash flow, category, location and dates from its state pages, but no contact and no seller type. |
| Max listings (`maxResults`) | 200 (pre-filled 20) | Hard cap on delivered rows, 1 to 10,000. |
| Only listings new since the last run (`newSinceLastRun`) | off | See the scheduling section. |
| Max run minutes (`maxRunMinutes`) | 25 | After this the actor stops reading, keeps what it delivered and finishes with a status message. Keep it below the run timeout. |
| Proxy (`proxyConfiguration`) | Apify proxy, automatic | Pages are read directly first. Only when a marketplace blocks a request (403, 429 or a challenge page) is it retried through up to two fresh Apify datacenter proxy sessions (or the datacenter groups or proxy URLs you choose); a challenge page or CAPTCHA is never solved, and no login or form is ever used. In 23 platform runs the retry was never needed. Apify residential proxies are never used: a residential group chosen here is ignored and the log says so. Your own third-party proxy URLs are used as you give them. |
| Save raw pages (`debugSaveRawPages`) | off | Diagnostics only. Stores up to 25 fetched pages in the run's key-value store. |

### Output

One dataset row per listing. Every key is always present; a value the marketplace does not show is `null`, never missing. Money is an integer in USD, dates are ISO 8601.

#### Example: Transworld, with broker contact

From a real platform test run (Florida, listing pages read), copied unchanged.

```json
{
  "source": "transworld",
  "source_listing_id": "2301-248452",
  "listing_url": "https://www.tworld.com/locations/florida/florida/listings/absentee-residential-and-commercial-lawn-maintenance-business",
  "title": "Absentee Residential and Commercial Lawn Maintenance Business",
  "description": "Over 6,000 in Recurring Revenue. Turnkey operation with vehicle and equipment included. Owner is hands-off currently. staff in place. Residential and Commercial clientele. Miami Beach area. Lots of room to grow and expand. Wont last long. Call today 407-893-1627.",
  "category": "Lawn/Landscaping",
  "subcategory": null,
  "location": {
    "city": "Miami",
    "county": "Miami-Dade County",
    "state": "Florida",
    "state_code": "FL",
    "country": "US",
    "raw": "Miami, Miami-Dade County, Florida"
  },
  "asking_price": 75000,
  "asking_price_text": null,
  "cash_flow": 25000,
  "revenue": 100000,
  "ebitda": null,
  "inventory": null,
  "ffe": 40000,
  "real_estate_included": null,
  "currency": "USD",
  "established_year": 2005,
  "employees": 2,
  "reason_for_selling": "Moving",
  "seller_type": "broker",
  "broker": {
    "name": "Adam Lawson",
    "brokerage": "Transworld Business Advisors (Orlando)",
    "phone": "(407) 745-0468",
    "email": "alawson@tworld.com",
    "profile_url": null,
    "contact_basis": "plain_text"
  },
  "listing_status": null,
  "posted_at": null,
  "updated_at": null,
  "source_updated_at": null,
  "first_seen_at": "2026-10-23T23:29:50Z",
  "is_new": null,
  "possible_duplicate_of": null,
  "quality_flags": [
    "inventory_zero_removed"
  ],
  "scraped_at": "2026-10-23T23:39:21Z",
  "fetch": {
    "tier": "direct",
    "detail_fetched": true
  }
}
```

#### Example: BusinessesForSale.com, broker-listed, no phone or email

From a real platform test run (Florida, restaurants, listing pages read), copied unchanged. The marketplace itself files this restaurant under "General Services"; the actor reports the category as the marketplace names it.

```json
{
  "source": "businessesforsale",
  "source_listing_id": "3893907",
  "listing_url": "https://us.businessesforsale.com/us/profitable-full-service-restaurant-in-prime-area.aspx",
  "title": "Profitable Full-Service Restaurant In Prime Area For Sale",
  "description": "A rare opportunity to acquire an established, full-service restaurant and bar located in a high-traffic corridor in Marion County, Florida. The business benefits from strong brand recognition, diversified revenue streams, and consistent year-round demand driven by both local and visitor traffic.\nThe operation is fully built-out and professionally managed, allowing for minimal owner involvement while maintaining strong daily operations. Multiple income channels, private event capabilities, and efficient staffing structure create both lifestyle appeal and investor upside. Significant growth potential exists through expanded marketing, events, catering, and operational efficiencies.",
  "category": "General Services Businesses",
  "subcategory": null,
  "location": {
    "city": "Ocala",
    "county": null,
    "state": "Florida",
    "state_code": "FL",
    "country": "US",
    "raw": "Ocala, Florida, US"
  },
  "asking_price": 295000,
  "asking_price_text": "$295,000",
  "cash_flow": 92731,
  "revenue": 1466624,
  "ebitda": null,
  "inventory": 25000,
  "ffe": 75000,
  "real_estate_included": false,
  "currency": "USD",
  "established_year": null,
  "employees": 30,
  "reason_for_selling": null,
  "seller_type": "broker",
  "broker": {
    "name": null,
    "brokerage": "Ocala Business Brokers, Inc.",
    "phone": null,
    "email": null,
    "profile_url": "https://us.businessesforsale.com/us/agents/ocala-business-brokers-inc-a1",
    "contact_basis": "none"
  },
  "listing_status": "quick_sale",
  "posted_at": null,
  "updated_at": null,
  "source_updated_at": null,
  "first_seen_at": "2026-10-23T23:13:59Z",
  "is_new": null,
  "possible_duplicate_of": null,
  "quality_flags": [
    "established_shown_as_age"
  ],
  "scraped_at": "2026-10-23T23:14:35Z",
  "fetch": {
    "tier": "direct",
    "detail_fetched": true
  }
}
```

#### Example: BizBen, broker-listed, hidden asking price

From a test run of the actor on a saved copy of a real BizBen listing page, copied unchanged. The seller hides the asking price, so `asking_price` is `null` and `asking_price_text` keeps the page's own words.

```json
{
  "source": "bizben",
  "source_listing_id": "5092472",
  "listing_url": "https://www.bizben.com/business-for-sale/high-net-jewelry-mfg-equipment-distributor-for-sale-5092472",
  "title": "High Net Jewelry MFG Equipment Distributor for Sale",
  "description": "The Company is a specialized distributor of European jewelry-manufacturing equipment and related production technologies serving customers across North America. Revenue is generated through equipment sales and a growing stream of recurring aftermarket revenue, including consumables, spare parts, technical support, training, and extended warranty programs. The business benefits from established supplier relationships, technical expertise, and an asset-light operating model that combines logistics coordination, financing support, and customer service into a differentiated value proposition. With an expanding installed base and strong supplier partnerships, the Company is well positioned to drive continued growth through both new equipment sales and recurring customer spend.\nNDA is required to receive a comprehensive Confidential Information Memorandum (CIM) crafted by ProNova Partners.\nDetailed Information\nFacilities: The Company operates from office and warehouse facilities that support inventory management, logistics coordination, and timely customer fulfillment.\nCompetition: The Company operates in a fragmented market alongside larger diversified industry suppliers, specialized equipment distributors, and direct manufacturer channels. The business differentiates itself through established supplier relationships, specialized technical expertise, responsive customer support, and a comprehensive service offering spanning equipment sales, logistics, installation, training, consumables, and aftermarket support.\nGrowth & Expansion: Significant growth opportunities exist through the expansion of sales and business development resources, deeper penetration of the existing customer base, the addition of new supplier relationships and technologies, broader marketing initiatives, expanded geographic coverage, and further development of recurring aftermarket revenue streams.",
  "category": "Wholesale",
  "subcategory": "Distributor & Wholesale Distribution",
  "location": {
    "city": "Los Angeles",
    "county": "Los Angeles County",
    "state": "California",
    "state_code": "CA",
    "country": "US",
    "raw": "Los Angeles, Los Angeles County, California"
  },
  "asking_price": null,
  "asking_price_text": "Call/Email",
  "cash_flow": 680288,
  "revenue": 1873652,
  "ebitda": null,
  "inventory": null,
  "ffe": null,
  "real_estate_included": null,
  "currency": "USD",
  "established_year": 2021,
  "employees": 1,
  "reason_for_selling": "Founder pursuing a transition of ownership to support the continued growth and scaling of the business.",
  "seller_type": "broker",
  "broker": {
    "name": "Rick Carlson",
    "brokerage": "ProNova Partners",
    "phone": "(833) 776-6682",
    "email": "info@pronovapartners.com",
    "profile_url": "https://www.bizben.com/business-brokers/rick-carlson-31407",
    "contact_basis": "plain_text"
  },
  "listing_status": "available",
  "posted_at": "2026-10-23T13:56:11Z",
  "updated_at": "2026-10-23T13:56:16Z",
  "source_updated_at": "2026-10-23T13:56:16Z",
  "first_seen_at": "2026-10-24T16:25:08Z",
  "is_new": null,
  "possible_duplicate_of": null,
  "quality_flags": [
    "price_undisclosed"
  ],
  "scraped_at": "2026-10-24T16:25:08Z",
  "fetch": {
    "tier": "direct",
    "detail_fetched": true
  }
}
```

#### Field reference

- **Identity:** `source`, `source_listing_id`, `listing_url`, `title`, `description` (at most 2,000 characters; index-only rows carry the short excerpt), `category`, `subcategory`.
- **Where:** `location` with `city`, `county`, `state` (full name), `state_code`, `country` (US) and `raw` (the text exactly as shown).
- **Money:** `asking_price`, `cash_flow` (cash flow or seller's discretionary earnings), `revenue`, `ebitda`, `inventory`, `ffe` (furniture, fixtures and equipment), `currency` (USD). `asking_price_text` keeps the text as shown, for example a range or "Undisclosed".
- **Business facts:** `real_estate_included`, `established_year`, `employees`, `reason_for_selling`.
- **Seller:** `seller_type` (`broker`, `owner` or `unknown`) and `broker` with `name`, `brokerage`, `phone`, `email`, `profile_url` and `contact_basis`.
- **Dates:** `posted_at` (BizBen and Empire Flippers show a real one), `updated_at`, `source_updated_at` (raw last-modified from the marketplace's own feed; BizBen's own update timestamp, refreshed in bulk for promoted listings, so not an edit date), `first_seen_at` (when this actor first delivered the listing for this search), `scraped_at`.
- **Status and quality:** `listing_status`, `is_new` (true when newSinceLastRun is on, `null` otherwise), `possible_duplicate_of` (source:id of an earlier row in the same run), `quality_flags` (for example `price_range`, `price_undisclosed`, `territory_ad`, `detail_blocked`, `online_business`, `date_unknown`, `syndicated_from_transworld`, `franchise_resale`, `location_hidden`, `contact_not_in_page_text`) and `fetch` with the connection `tier` and whether the listing page was read.

Nothing is invented. Price ranges and "Undisclosed" give `asking_price` `null` with the text kept in `asking_price_text`. A `$0` revenue or cash flow placeholder (seen on Transworld) becomes `null` with a flag such as `cash_flow_zero_removed`. An age such as "10 years" is never turned into a year established.

### What a run costs and how long it takes

Pricing is pay per event; see the pricing tab for the current prices. The events are:

- `apify-actor-start`: once per run, scaled by the run memory.
- `listing`: a listing row is delivered (index-only or detailed).
- `broker-contact`: the delivered row has a plain-text broker phone or email. Rows with no public contact are not charged this event.

Units are charged only after the row is saved, and the charged event counts equalled the delivered rows in every settled test run. Set a maximum cost per run in Console: the actor works out how many listings the cap can pay for, lowers Max listings up front, and never saves a row that cannot be billed. If only the contact event runs out, the row is delivered without phone and email and marked `skipped_budget`. A test with a small cap stopped cleanly with the status "Budget reached: 2 listings delivered".

If a run is aborted from the Console and resurrected, it carries on without delivering the rows it already saved again: a row is never delivered twice, and after a crash at most one row's charge may repeat. In a test, a Transworld run aborted after 71 seconds and then resurrected finished with 30 distinct listings and charged event counts of 30 listings and 30 broker contacts (plus one actor-start event for each container start).

Measured on the Apify platform on 2026-10-23 at 512 MB, all requests on the direct connection with none blocked:

| Run | Rows | Time |
|---|---|---|
| BusinessesForSale.com, Florida, list pages only | 20 | 7.5 seconds |
| BusinessesForSale.com, Florida, listing pages read | 20 | 28.9 seconds |
| Empire Flippers, all of the US | 40 | 7.2 seconds |
| Transworld, Texas, listing pages read | 12 | 158.7 seconds |
| Transworld, 1-minute limit | 4 | 65.6 seconds |
| Transworld, Florida, list pages only (fast index route) | 15 | 38.4 seconds |
| BusinessesForSale.com, Florida, category "restaurants", listing pages read | 25 | 56.7 seconds |
| Transworld, Texas, category "restaurants", listing pages read, before the fix described below | 7 | about 14 minutes (the test run was cut at its own 15-minute timeout, so it could not finish its 10 rows) |
| Transworld, Texas, category "restaurants", listing pages read, current build | 10, all with broker phone and email | 129 seconds |
| Transworld, Florida, listing pages read | 8, all with broker phone and email | 100 seconds |
| Three sources, category "restaurants", Florida and Texas | 42 (23 BusinessesForSale.com, 19 Transworld) | about 25 minutes, ended at the 25-minute limit |

BizBen is read at one request per second like the other open marketplaces. Its state pages carry 40 listings each, and a listing page is opened only for rows that pass the list-page filters. A US-wide search reads the 51 state pages first (about 51 requests, under a minute, plus a second page for states whose first page still reaches into your date window) and then opens one listing page per row that passes the list-page filters, so 200 rows need roughly 250 requests, about 4 to 5 minutes at one per second. On the Apify platform (direct connection, no proxy) a California search that read 20 listing pages took 29 seconds.

Transworld is slow on purpose: its robots.txt asks for one request every 10 seconds, so expect about 6 listings per minute. BusinessesForSale.com and Empire Flippers are read at one request per second. The three-source run above is dominated by Transworld, where a category search opened 149 listing pages one by one to find 19 matches. What the confirmation runs proved about Transworld: a state search with "Read each listing page" switched off reads Transworld's search index, 9 listings per page at 10 seconds per page (15 Florida rows in 38 seconds, list data only: no broker contact, and the listing's web address as its id). Reading the full listing page, which is what brings the broker's phone and email, costs one more request of 10 seconds per listing. A search with a category or price filter asks the state's search index first and then opens only the listings that match, one request of 10 seconds each, but that fast index route is not reliable (see the end of this paragraph). Transworld answers a filtered search with the whole state catalogue in a single response (746 cards for Texas, about 6.7 MB) and does not apply the category filter itself, so the actor applies the category and price filters to those cards. A Texas restaurants search for 10 listings with broker phone and email took 129 seconds, against about 14 minutes for 7 listings before this was fixed. Transworld listing pages are requested at their canonical lowercase address, so each page costs one 10-second slot (8 Florida listings with broker contacts in 100 seconds). Fill rates in a Florida BusinessesForSale.com run of 20 listings with pages read: asking price 19, cash flow 15, revenue 16, employees 8, reason for selling 10 and year established 3 (most pages show an age instead of a year, which is left `null`). In a Texas Transworld run of 12 listings, all 12 had a broker name, phone and email. A category or price search WITH a state tries Transworld's search index first and then reads only the matching listing pages. That fast route worked in one test run (Texas, 10 rows in 129 seconds) and fell back to the slower route in others (California, and the nationwide searches); the actor falls back automatically, the rows are the same, only the run is slower (one listing page per candidate at 10 seconds each). A nationwide category search (no state) gets no usable index from Transworld and falls back to reading one listing page per candidate at 10 seconds each: in testing, 10 nationwide restaurant listings with broker contacts took about 8 minutes (run D1YP3I5QXl8vaFLaC), so give a state whenever you can.

The deadline valve (`maxRunMinutes`) ends the run with exit code 0 and a status message, and keeps every row already delivered. The default run options are 512 MB of memory and a 1,800-second (30-minute) timeout, which is why the default Max run minutes is 25.

### Scheduling and deal-flow alerts

1. Create a schedule for the actor in Console (daily is typical).
2. Use the same search every time and switch on "Only listings new since the last run".
3. Pick Max listings large enough for one run's worth of new listings.

Each run delivers only listings not delivered before for the same search and remembers their ids in a named key-value store called `bfs-seen` in your own Apify account. The search is identified by marketplaces, categories, keywords, locations, price, cash flow, revenue and seller filters. Changing any of those starts a fresh history; changing the caps or the date window does not. Rows from such runs carry `is_new: true`.

What we measured: two runs of the same BusinessesForSale.com Georgia search with a cap of 30: the first delivered 30 listings and the second skipped those 30 and delivered 30 different ones. A later daily-style twin on the same Ohio query delivered only listings that had not been delivered before (20 different ones) and its status line read "20 skipped as already seen", so you can see how much the history filtered. A run with nothing new delivers 0 rows and says so.

Please note: neither Transworld nor BusinessesForSale.com shows a posting date, so "new" means "not delivered to you before", not "posted today". The first run of a new search has no history, so it delivers everything it finds up to Max listings and seeds the history. Empire Flippers does show true dates (`posted_at`), and so does BizBen: with BizBen a window such as "posted within 7 days" is exact, and a scheduled US-wide search is cheap because the actor reads the state pages and opens a listing page only for listings it has not delivered before.

### Limits and honesty

- **Partial coverage.** The two largest US marketplaces (BizBuySell and BizQuest) block automated access and are not covered. Treat this as one slice of the market.
- **No posted dates on Transworld or BusinessesForSale.com.** `posted_at` is empty there; BizBen and Empire Flippers show real ones. BusinessesForSale.com's `updated_at` comes from its sitemap's last-modified date, which is a change date, not a creation date, and is read only when you set the date window. New-since-last-run relies on the seen store.
- **Contacts are uneven.** Transworld and BizBen rows carry a phone and email (BizBen: only when it is printed on the page; its rows copied from Transworld carry an email only). BusinessesForSale.com shows no public phone or email, and about a third of its test rows were owner-listed with no seller named.
- **Categories can be loose.** BusinessesForSale.com also lists related-category ads in a category search. A preset keeps a listing only when its own primary category or its title matches, and with details off a category search matches on the title only. We still saw ads filed by the marketplace itself under Restaurants that were side businesses from one broker.
- **Duplicates and synthetic ads are flagged, not removed.** Near-identical ads from one lister (for example "territory" ads with a price band and no financials) get `possible_duplicate_of` or `territory_ad`. The row is still delivered and billed; you decide what to do with it.
- **The same business can appear on several marketplaces.** Rows are not merged across sources. About half of BizBen's listings are Transworld listings republished there: they are skipped when Transworld is selected too, and flagged `syndicated_from_transworld` when it is not. Other brokers also list one business on several sites; `possible_duplicate_of` links rows with the same title, state and price within a run.
- **BizBen city and seller details.** BizBen lets sellers hide the city (or the whole location); a hidden location cannot match a state or city search. Without the "For Sale By Owner" tag, an account type of "other" or "non-broker" gives `seller_type` `unknown`.
- **BizBen date ordering.** Its state pages are ordered by last update, not by posting date, and its paid FastTrack listings come first with an update time that is refreshed every day. The actor therefore checks every listing against its own posting date, ignores FastTrack listings when it decides to stop, and stops reading a state when the last ordinary listings of a page were all last updated before your window starts. In a state with a very long FastTrack block, new postings behind it can be missed after 15 pages without a match.
- **Sold, under-contract, under-LOI and pending listings** that the marketplace labels as such are not delivered and not billed. On BizBen only listings whose status is Available are delivered.
- **Transworld location filter.** Candidates are found through the listing office's state, then each listing's own location is read and must match your filter: a business listed by an office in another state is missed, and an out-of-state business listed by an in-state office is dropped. With a small Max listings you may only see the first offices in the marketplace's own order; the actor spreads the reads across offices to reduce this.
- **Transworld returns the most expensive listings first.** Its search index is sorted by price, highest first, so a small Max listings returns the most expensive matches. Raise Max listings (or add a price ceiling) to reach cheaper ones.
- **Transworld does not filter by category itself.** Its server ignores the category filter and returns the whole state's catalogue in one large response, and the actor applies your category and price filters to it. Results are correct, but each such search downloads a response of several megabytes.
- **County or city.** Bare county names are recognised only from an interim list of 36 county names across 11 states, so some county-level locations may land in `city` instead of `county`.
- **Non-US listings** are not delivered for a "United States" search.
- A listing page that fails to load is skipped (and not billed) or, for BusinessesForSale.com, delivered from its list-page data with the flag `detail_unavailable` or `detail_blocked`. Transworld's page layout could change; if five pages in a row cannot be read the actor stops reading that marketplace and says so in the status message.
- Data on the marketplaces is added by brokers and owners and can be wrong or out of date. Confirm anything that matters with the broker.

### FAQ

#### Does it give me a broker's phone number and email?

For Transworld and BizBen listings, yes: the advisor's (or on BizBen the broker's or owner's) name, phone and email are plain text on their pages and the actor returns them; BizBen copies of Transworld listings carry the email only. For BusinessesForSale.com you usually get the broker's name (broker-listed ads only) and a profile link, but no phone or email, because the site publishes none. For Empire Flippers there is no person. A contact that is not plain text is never guessed.

#### Why does it read BizBen when BizBen's terms forbid robots?

BizBen's terms of use forbid using a robot, spider or automatic device to copy its pages and forbid data-mining tools without written permission. The publisher of this actor decided to read BizBen anyway and accepted that position. The actor keeps to BizBen's robots.txt, reads at one request per second, never logs in and never submits a form. If you need a source whose terms allow automated reading, deselect `bizben` in the Marketplaces input.

#### Will I pay twice for a business that is on BizBen and on Transworld?

Not when both marketplaces are selected: BizBen's copies of Transworld listings are skipped, and the same business from two different sites is flagged with `possible_duplicate_of` when the title, state and price match. A business that a broker lists separately on several sites can still appear once per site. When Transworld is also selected, Transworld listings come from Transworld and BizBen's republished copies are skipped, so a slow Transworld run (one request per 10 seconds) may deliver fewer of them than a BizBen-only run.

#### Why is BizBuySell not included?

BizBuySell and BizQuest block automated access. A blocked request is retried through up to two fresh Apify datacenter proxy sessions; a challenge page or CAPTCHA is never solved, and no login or form is ever used. They are the biggest US marketplaces, so this actor covers part of the market, not all of it.

#### Can brokers use it to find sellers?

Yes. Run it by state and category, and filter to owner-listed ads (`sellerType` = owner) on BusinessesForSale.com to see businesses for sale without a broker. Owner-listed BusinessesForSale.com rows are anonymous, so the row gives you the business, the price and the listing link, not a contact. On BizBen, owner-listed ads carry the seller's own name, phone and email when the page prints them (they are personal data; see the legal note).

#### Can lenders and buyers get alerts on new listings?

Yes. Schedule a daily run with your state, category and price band and "Only listings new since the last run" on. Each run returns only listings you have not received.

#### Can I filter by price, cash flow and revenue?

Yes: `minPrice`, `maxPrice`, `minCashFlow` and `minRevenue`. A listing that does not show the number you filter on is left out, and a price range counts when it overlaps your band.

#### Do I need my own proxy?

No. Pages are read directly. If a marketplace blocks a request (403, 429 or a challenge page), the actor retries it through up to two fresh Apify datacenter proxy sessions; a challenge page or CAPTCHA is never solved, and no login or form is ever used. In 23 platform runs the retry was never needed. It never uses Apify residential proxies. You may give your own proxy URLs.

#### Why did I get fewer rows than Max listings?

Because fewer listings matched or the run hit its time or cost limit. The status message at the end of the run names the reason, including inputs that were ignored or not recognised and sources that were skipped (for example Empire Flippers on a state search).

#### How fresh is the data?

Every run reads the marketplaces live. Empire Flippers and BizBen dates are real. For the others, use a scheduled new-since-last-run search for freshness.

### Legal note

BizBen: BizBen's terms of use forbid using any robot, spider or other automatic device to monitor or copy its pages and forbid data mining or extraction tools without its written permission. This actor reads BizBen on the publisher's decision; the publisher knows what the terms say and accepted that position. That decision is not a permission from BizBen. You are responsible for your own use of the data, and you can switch BizBen off by leaving `bizben` out of the Marketplaces input. The actor honours BizBen's robots.txt, reads one page per second, never reads the Flippa listings that BizBen republishes (Flippa's own terms forbid data gathering) and skips the Transworld listings republished there when Transworld is selected.

The actor reads public listing pages and a public API, one request per second per marketplace (one per 10 seconds for Transworld, as its robots.txt asks), and honours robots.txt. It does not log in, solve challenges or submit forms. Broker names, phones and emails are personal data in many jurisdictions: you are responsible for lawful use, including consent and opt-out rules for outreach (for example CAN-SPAM, TCPA and GDPR). This README is not legal advice.

### Changelog

- 0.1.x (October 2026): BizBen added as a fourth marketplace (posting dates, broker and owner contacts; the owner decided to read it despite its terms). First release: Marketplaces: Transworld Business Advisors, BusinessesForSale.com (US) and Empire Flippers. Pay per event: listing, broker-contact and actor start.

# Actor input Schema

## `sources` (type: `array`):

Marketplaces to read. Transworld Business Advisors (named advisor with phone and email; its robots.txt asks for one request every 10 seconds, so about 6 listings per minute), BusinessesForSale.com US (largest open catalogue; broker name only, no phone/email), Empire Flippers (online businesses only, no state) and BizBen (California-heavy catalogue with the broker or owner name, phone and email as plain text and the real posting date; BizBen's terms forbid automated access, see the README legal section; listings it republishes from Transworld are skipped when Transworld is selected too, and listings it republishes from Flippa are never read). The requested results are shared fairly between the marketplaces; the order sets who gets the extra row when they do not divide evenly. BizBuySell, BizQuest and LoopNet are not covered. An empty list reads ALL marketplaces (the run logs a warning and its status message says so); to read fewer, list the ones you want.

## `categories` (type: `array`):

Optional. Presets mapped to each marketplace's own categories: restaurants, food, retail, services, manufacturing, online, healthcare, construction, automotive, franchises, transportation, wholesale, professional-services, beauty-fitness, education-childcare, technology, leisure-hospitality. BusinessesForSale lists related-category ads in a category search, so a preset keeps a listing only when its own primary category or its title matches. Any other text is matched against the listing's category and title. Leave empty for all categories.

## `keywords` (type: `array`):

Optional. A listing matches when its title, category or description contains any of these words.

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

US state names or codes (Florida, TX), 'City, ST' (Miami, FL) or 'United States'. A listing matches when it is in any of them. Empire Flippers lists online businesses without a state, so it only contributes to 'United States'. BizBen hides the city of many listings, so a city search finds only those that show it.

## `minPrice` (type: `integer`):

Optional. Listings without a disclosed asking price are left out when this is set (a price range counts when it overlaps).

## `maxPrice` (type: `integer`):

Optional. Listings without a disclosed asking price are left out when this is set (a price range counts when it overlaps).

## `minCashFlow` (type: `integer`):

Optional. Listings that do not show a cash flow are left out when this is set.

## `minRevenue` (type: `integer`):

Optional. Listings that do not show revenue are left out when this is set. BusinessesForSale.com shows revenue on its list pages; Transworld rows are read from the listing page.

## `postedWithinDays` (type: `integer`):

Optional. Keeps listings posted or updated within this many days when the marketplace shows a date (BizBen: the true posting date, so it works exactly; Empire Flippers: listing date; BusinessesForSale.com: last-modified date from its sitemap). Transworld shows no dates: its rows are kept and flagged date_unknown.

## `sellerType` (type: `string`):

any, broker or owner. Broker/owner is known from the listing page only (Transworld and Empire Flippers are always brokers; BizBen says broker or owner on its listing pages); rows where it is not shown are left out when broker or owner is chosen.

## `includeDetails` (type: `boolean`):

On: each listing page is read for the full description, inventory, furniture and fixtures, employees, year established, reason for selling and the broker. Off: list-page data only (faster, fewer requests). Transworld: with a category, price or cash-flow filter, or with this switch off, the search index is read (9 listings per request) and only matching listings are opened; off gives index data only (no revenue, description or broker contact). BusinessesForSale with a category: off matches the category on the title only, because the category is only known from the listing page. BizBen: with this switch off its rows come from the state pages (price, revenue, cash flow, category, location and dates, no broker contact); on, a US-wide search without filters reads the newest listings first.

## `maxResults` (type: `integer`):

Hard cap on delivered rows for this run, shared fairly between the selected marketplaces. If maxTotalChargeUsd pays for fewer, the run stops there and the status says so.

## `newSinceLastRun` (type: `boolean`):

For scheduled runs (daily deal-flow alerts): deliver only listings not delivered before for the same search (marketplaces, categories, keywords, locations, price, cash flow, revenue and seller filters). Delivered listing ids are remembered in a named key-value store 'bfs-seen' in your account.

## `maxRunMinutes` (type: `integer`):

After this many minutes the actor stops reading, keeps what it delivered and finishes with a status message. Keep it below the run timeout.

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

Pages are read directly first. Only when a marketplace blocks a request is it retried through an Apify datacenter proxy (or the datacenter groups or proxy URLs you choose here). Apify residential proxies are never used: a RESIDENTIAL group chosen here is ignored and the run log says so. Your own third-party proxy URLs are used as you give them.

## `debugSaveRawPages` (type: `boolean`):

Diagnostics only: stores up to 25 fetched pages of this run in its key-value store (keys raw\_<source>*<kind>*<id>). Leave off.

## Actor input object example

```json
{
  "sources": [
    "transworld",
    "businessesforsale",
    "empireflippers",
    "bizben"
  ],
  "categories": [],
  "keywords": [],
  "locations": [
    "Florida"
  ],
  "sellerType": "any",
  "includeDetails": true,
  "maxResults": 20,
  "newSinceLastRun": false,
  "maxRunMinutes": 25,
  "proxyConfiguration": {
    "useApifyProxy": true
  },
  "debugSaveRawPages": false
}
```

# Actor output Schema

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

One row per business listed for sale on a marketplace.

## `runStats` (type: `string`):

Pages read per source, filter funnel, charges and connection tiers used in this run.

# 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 = {
    "sources": [
        "transworld",
        "businessesforsale",
        "empireflippers",
        "bizben"
    ],
    "locations": [
        "Florida"
    ],
    "maxResults": 20,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("buff_pineapple/businesses-for-sale-leads").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 = {
    "sources": [
        "transworld",
        "businessesforsale",
        "empireflippers",
        "bizben",
    ],
    "locations": ["Florida"],
    "maxResults": 20,
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("buff_pineapple/businesses-for-sale-leads").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 '{
  "sources": [
    "transworld",
    "businessesforsale",
    "empireflippers",
    "bizben"
  ],
  "locations": [
    "Florida"
  ],
  "maxResults": 20,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call buff_pineapple/businesses-for-sale-leads --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,buff_pineapple/businesses-for-sale-leads"
        }
    }
}
```

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/5VlF9j8qs1ZYgdXRO/builds/29ENghAfJ79lktNnR/openapi.json
