BizQuest Scraper $1๐ฐ Businesses, Franchises & Asset Listings
Pricing
from $1.00 / 1,000 listing results
BizQuest Scraper $1๐ฐ Businesses, Franchises & Asset Listings
Extract business-for-sale, franchise, and asset listings from BizQuest. Search by category, US state, asking price, or use BizQuest URLs. Returns 50+ fields, including asking price, location, photos, broker name and phone where available, ready for CRM, deal pipeline, or spreadsheet use.
Pricing
from $1.00 / 1,000 listing results
Rating
0.0
(0)
Developer
Abot API
Maintained by CommunityActor stats
1
Bookmarked
10
Total users
2
Monthly active users
3 days ago
Last modified
Categories
Features
Share
BizQuest Scraper: Business-for-Sale Listings, Broker Contacts and Financials
BizQuest Scraper turns BizQuest into a clean deal-flow feed. Get the asking price, cash flow, EBITDA, category, location and the broker's full contact block (name, phone, brokerage, profile link) for every business-for-sale, franchise and asset listing. Search by category, US state and price band, or paste BizQuest search and category links directly. Turn on full detail mode for gross income, inventory, employee counts and reasons for selling, then export to JSON, CSV or Excel, or pull results straight into your app through the API.
Why This Scraper?
- 50+ fields on every listing, including the full broker contact block (name, phone, brokerage, profile link), something many quick scrapers skip.
- Two ways to find listings. Filter by category, US state, keyword and asking price, or paste any BizQuest search or category URL and skip the filters entirely.
- Optional full detail mode. Turn on
includeDetailsfor about 30 more fields per listing: gross income, inventory, FF&E, employee counts, reasons for selling, financing and year established. - No page limit by default.
maxPagesdefaults to unlimited, and the run stops on its own once the site's own reported total is reached.maxListings(default 20,0for unlimited) is the one cap you set. - Two different ways to keep a search current. Resume one interrupted run from its run or dataset id, or turn on incremental mode to schedule the same search repeatedly and get back only what changed.
- Nothing is dropped. Every record keeps the complete source item under
raw, so a field the site adds later still reaches your dataset without a code change. - Keeps working through refused connections. BizQuest's edge refuses ordinary page requests intermittently, so the default connection is Residential (country US) and listing data is read through the site's own search service rather than the search web pages. When a connection is refused, the actor retries with a different one and, as a last resort, over a backup connection, logging plainly what happened. A run that could not load a single results page ends as failed with a clear message instead of an empty dataset.
Use Cases
- Business brokers and M&A advisors: track new listings and price movements across categories and states to feed a prospecting pipeline.
- Buy-side searchers and search funds: build a filtered deal-flow list by industry, price band or state, and monitor it on a schedule for new matches.
- Market researchers and analysts: measure asking price, cash flow and EBITDA trends across categories and regions over time.
- Franchise resale trackers: use the franchise fee and capital fields to watch franchise resale activity by category.
- Lead generation for lenders and service providers: use the broker contact fields to build outreach lists tied to active listings.
Data You Get
Sample shape, values are illustrative placeholders, not from a live listing.
| Field | Example |
|---|---|
id | 20000001 |
title | "Sample Established Service Company" |
url | "https://www.bizquest.com/business-for-sale/sample-listing/BW20000001/" |
description | "Recurring-revenue service company with a stable client base." |
askingPrice | 750000 |
cashFlow | 220000 |
ebitda | 180000 |
category | "Home & Garden" |
location | "Florida" |
region | "FL" |
stateName | "Florida" |
isFranchise | false |
initialFee | null |
initialCapital | null |
brokerName | "Jane Doe" |
brokerCompany | "Sample Brokerage" |
brokerPhone | "+10000000000" |
brokerProfileUrl | "/business-broker/sample-brokerage/jane-doe/BW00000/" |
image | "https://images.bizquest.com/shared/listings/000000000.jpg" |
hotProperty | false |
recentlyAdded | true |
raw | the complete source item for this listing |
Every record also carries, whenever BizQuest provides them, the listing's own fields promoted to the top level: header, city, county, zip, streetAddress, employees, realEstate, homeBased, absenteeOwner, relocatable and similar (a field BizQuest does not send is simply absent, never a placeholder). The numeric and text fields are type-checked before output, so a malformed upstream value becomes null rather than stopping the run. Every record also carries images (the full photo array), locationCrumbs, categoryId, listingTypeId, leaseRatePerSquareFoot, realEstateIncludedInAskingPrice, financingTypeId, the full contactInfo block (broker contact, verbatim) and diamondMetaData block, plus sourceUrl and scrapedAt. With includeDetails on, each record also gains grossIncome, inventory, ffe, employeesFullTime, employeesPartTime, yearEstablished, buildingSquareFeet, summary, support, financingOptions, reasonsForSelling, competition, growth, fullDescription, leaseTerms and the full detail object under detailRaw, and cash flow, gross income and EBITDA fill in wherever the seller discloses them on the detail page. With incremental mode on, every returned record also carries changeType, changedFields, firstSeenAt and lastSeenAt.
Dataset views
The dataset has four views in the Console: Listings Overview (price, cash flow, EBITDA, category, location, broker, change columns), Broker Contacts, Listing Details (the includeDetails fields) and Changes (incremental changeType, changedFields, first and last seen).
How to Use
- Pick a mode:
search(build a filtered search from category, state, price band and keyword) orurl(paste one or more BizQuest search or category links; filters are ignored in this mode). - For search mode, fill in the category or sub-category, locations, price, cash-flow, listing-age and year filters and keyword you want. For URL mode, paste the links.
- Turn on Fetch full listing details if you want the extra financial and description fields.
- Set Max listings to control run size and cost, then click Start.
Search one state:
{"mode": "search","locations": ["Florida"],"maxListings": 100}
Category plus state plus price band:
{"mode": "search","category": "Food & Beverage","locations": ["California"],"minPrice": 200000,"maxPrice": 800000,"includeDetails": true,"maxListings": 100}
Paste BizQuest URLs (filters are ignored in this mode):
{"mode": "url","urls": ["https://www.bizquest.com/businesses-for-sale-in-florida-fl/","https://www.bizquest.com/food-and-beverage-businesses-for-sale/"],"maxListings": 200}
Supported URL shapes (URL mode)
URL mode with no URLs pasted now runs the example list below (one real URL per supported shape) instead of stopping with an error. Pasted URLs on m.bizquest.com or plain bizquest.com are treated as www.bizquest.com.
| Shape | Example |
|---|---|
| Nationwide search | https://www.bizquest.com/businesses-for-sale/ |
| Nationwide, paginated | https://www.bizquest.com/businesses-for-sale/page-2/ |
| State search | https://www.bizquest.com/businesses-for-sale-in-florida-fl/ |
| State, paginated | https://www.bizquest.com/businesses-for-sale-in-florida-fl/page-2/ |
| City search | https://www.bizquest.com/businesses-for-sale-in-miami-fl/ |
| County search | https://www.bizquest.com/businesses-for-sale-in-miami-dade-county-fl/ |
| Top-level category, nationwide | https://www.bizquest.com/food-and-beverage-businesses-for-sale/ |
| Category and state | https://www.bizquest.com/food-and-beverage-businesses-for-sale-in-florida/ |
| Sub-category, nationwide | https://www.bizquest.com/restaurants-for-sale/ |
| Sub-category and state | https://www.bizquest.com/restaurants-for-sale-in-florida/ |
| State search with sort link | https://www.bizquest.com/businesses-for-sale-in-florida-fl/?q=%3Ff_srt%3Dprice-asc |
| Mobile host | https://m.bizquest.com/businesses-for-sale-in-florida-fl/ |
| Broker profile (that broker's listings) | https://www.bizquest.com/business-broker/transworld-business-brokers/james-knox/BW29511/ |
Also accepted, but not listed above because each one has the same target as a listed shape: the older /buy-a-business-for-sale/search/ link (the site redirects it to the nationwide search, so it is read as /businesses-for-sale/) and a plain ?sort=price query on a search link (the site ignores it and serves the same page as the search without it; use the ?q= sort link above to actually sort). A broker directory (/florida-business-brokers/) is a page of brokers with no listings on it, and the broker-directory index /business-brokers/ does not exist, so those are skipped with a warning.
A pasted single-listing URL (/business-for-sale/<name>/BW<id>) returns that listing. In a ?q= link only the price or cash-flow sort is applied; any other filter inside ?q= is not supported and is logged as a warning (the page is walked unfiltered). The default list includes one broker-directory example (/florida-business-brokers/) so every confirmed page shape is represented; it yields no listings and is skipped with a warning per URL, like franchise brand pages are skipped with a warning per URL.
Recurring monitoring of the same search:
{"mode": "search","locations": ["Florida"],"incrementalMode": true,"maxListings": 0}
Run it from your code
Python:
from apify_client import ApifyClientclient = ApifyClient("<YOUR_APIFY_TOKEN>")run = client.actor("abotapi/bizquest-scraper").call(run_input={"mode": "search", "locations": ["Florida"], "maxListings": 100})for listing in client.dataset(run["defaultDatasetId"]).iterate_items():print(listing["title"], listing["askingPrice"])
JavaScript:
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });const run = await client.actor('abotapi/bizquest-scraper').call({ mode: 'search', locations: ['Florida'], maxListings: 100 });const { items } = await client.dataset(run.defaultDatasetId).listItems();
Or connect it to Make, Zapier, n8n, Google Sheets or webhooks from the Integrations tab.
Resume and recurring updates
- Resume (
resumeFromRunId) continues one specific interrupted run: paste its run id or dataset id and the actor skips every listing it already collected there, so this run returns only the delta and you don't pay twice. - Incremental mode (
incrementalMode) is for scheduled runs over the same search. Each listing is classifiedNEW,UPDATED(withchangedFields),UNCHANGED(suppressed and not billed unlessemitUnchangedis on), orEXPIRED(only after a run that scanned the whole tracked search withemitExpiredon). A listing only comes back classifiedREAPPEAREDafter it was previously markedEXPIREDand is then found again on a later run.stateKeynames or shares the stored state; otherwise it is derived automatically from your search filters, so different searches never mix state; changingchangeScopeorignoreFieldsForChangeskeeps the same state, so it never re-bills the catalogue. The scrape time, call-tracking phone numbers, ad-tier and sponsor ids, the result-rank offset, which result page it was found on, and the age badges (recently added, recently updated, hot property, price reduced) never count as a change, though they stay in the output.changeScopeset to price and cash flow only makes just the asking price, cash flow, EBITDA and the price-reduced flag decideUPDATED.compactUpdatesreturns shortUPDATEDandEXPIREDrows (ids, url, title, current figures andpriceChangeswith old and new values);NEWrows stay complete and compact rows do not bill the detail-enrichment event.expireAfterMissedScanswaits for N complete scans in a row before markingEXPIRED;EXPIREDmeans the listing was no longer found in the search, not proof that the business was sold.ignoreFieldsForChangesexcludes more fields, with dotted names such asraw.imgorcontactInfo.contactPhotofor nested keys.
Send results into your apps (MCP connectors)
Optionally pipe the scraped results into the apps you already use, via Model Context Protocol (MCP) connectors. This is an extra delivery step after the scrape, the Apify dataset is never changed.
What gets written to the connector: a condensed, human-readable summary of each record, not the full JSON. Each item becomes one entry with a title and its key fields flattened to plain text. The complete record always stays in the Apify dataset.
- Authorize a connector once under Apify > Settings > Integrations (Notion, Linear, Airtable, or Apify).
- Select it in the "Pipe results into your apps" input field. If the picker is empty, you haven't authorized a connector yet.
- For Notion, also set
notionParentPageUrlto the page where items should be created.
The connection is mediated by Apify's MCP proxy, so this actor never sees your third-party credentials. Leave the field empty to skip.
Input Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
mode | string | search | search builds a filtered search from the fields below, url walks pasted BizQuest URLs instead. |
category | string | (any) | Industry category dropdown (search mode). Leave empty for all categories. |
locations | array | none (prefill: ["Florida"]) | US states by name or two-letter code. One search runs per state. Leave empty for nationwide. |
keyword | string | none | Phrase to match in the listing title or description, applied after fetch. |
sortBy | string | (featured) | Server-side order by price or cash flow, low to high or high to low. Ranks the whole result set before paging. Leave empty for the site's featured order. |
minPrice | integer | none | Only keep listings at or above this asking price, in USD. Listings with no disclosed price are excluded when set. |
maxPrice | integer | none | Only keep listings at or below this asking price, in USD. |
subCategory | string | any | One BizQuest sub-category (for example Restaurants or Auto Body & Repair), applied through the site's own sub-category pages. It belongs to one parent category and replaces category when set. |
minCashFlow | integer | none | Only listings with cash flow at or above this amount in USD, applied by BizQuest's own search before paging, so it narrows the whole result set. The cash flow shown on list pages is often hidden by the site; turn on includeDetails to see it where the seller discloses it. |
maxCashFlow | integer | none | Only listings with cash flow at or below this amount in USD, applied the same server-side way as minCashFlow. |
listedWithinDays | integer | none | Only listings first posted in the last N days (for example 7 for this week's new deals), applied server-side. |
establishedAfterYear | integer | none | Only businesses established in or after this year, applied server-side. |
urls | array | one example of each supported URL shape (listed in the URL shapes table) | BizQuest URLs for URL mode. Filter fields above are ignored in this mode. Left empty in URL mode, the example list is used. |
sessionJarSeed | string (secret) | (empty) | One-time operator field: paste a cookie jar from a signed-in browser session; the actor stores and rotates it for broker-profile pages. Re-paste a fresh jar only if broker pages keep failing across many runs. Requires a 2048MB allocation. |
includeDetails | boolean | false | Adds about 30 more fields per listing: gross income, inventory, FF&E, full description, employees, reasons for selling, financing and year established. |
maxPages | integer | 0 | Optional bound on result pages (50 listings each) walked per search or URL. 0 means walk the whole catalog and stop on its own at the site's reported total, an empty page, or a page that repeats content already served. Does not cap listing count; use Max listings for that. |
maxListings | integer | 20 | The one cap on total listings collected (maximum 100000). 0 means unlimited. |
resumeFromRunId | string | none | ID of a previous run of this actor (or a dataset ID). Listings already in that dataset are skipped, so this run returns only new listings, a delta. |
incrementalMode | boolean | false | Turn on for recurring or scheduled monitoring of the same search. Returns only NEW and UPDATED listings by default, instead of the full result set every time. EXPIRED, and later REAPPEARED, appear only with emitExpired on. |
stateKey | string | none | Names the incremental-mode monitoring campaign explicitly. Leave empty to let the actor derive a key automatically from the search filters. |
emitUnchanged | boolean | false | Incremental mode only. Also return, and bill, listings that haven't changed, marked UNCHANGED. |
emitExpired | boolean | false | Incremental mode only. Also return, and bill, listings no longer found, marked EXPIRED, produced only after a complete, uncapped, non-resumed scan. |
expireAfterMissedScans | integer | 1 | Incremental mode only. Mark EXPIRED only after the listing is missing from this many complete scans in a row. |
changeScope | string | all | Incremental mode only. all or priceAndStock (asking price, cash flow, EBITDA and price-reduced flag only). |
compactUpdates | boolean | false | Incremental mode only. Short UPDATED and EXPIRED rows with priceChanges. |
ignoreFieldsForChanges | array | none | Incremental mode only. Field names or dotted paths (for example raw.img) that never count as a change. |
proxy | object | Residential US | Connection settings. Residential US is recommended and is the default. |
mcpConnectors | array | none | Optional: send a summary of each record to apps you authorized under Integrations. |
notionParentPageUrl | string | none | Notion connector only: page under which item pages are created. |
maxNotifyListings | integer | 50 | Cap on items written to each connector per run. Does not affect the dataset. |
Output Example
Sample shape, values are illustrative placeholders, not from a live listing.
{"id": 20000001,"listNumber": 20000001,"title": "Sample Established Service Company","url": "https://www.bizquest.com/business-for-sale/sample-listing/BW20000001/","description": "Recurring-revenue service company with a stable client base.","image": "https://images.bizquest.com/shared/listings/000000000.jpg","images": ["https://images.bizquest.com/shared/listings/000000000.jpg"],"askingPrice": 750000,"cashFlow": 220000,"ebitda": 180000,"location": "Florida","region": "FL","stateName": "Florida","category": "Home & Garden","categoryId": 316,"isFranchise": false,"brokerName": "Jane Doe","brokerCompany": "Sample Brokerage","brokerPhone": "+10000000000","brokerProfileUrl": "/business-broker/sample-brokerage/jane-doe/BW00000/","contactInfo": { "contactFullName": "Jane Doe", "brokerCompany": "Sample Brokerage" },"hotProperty": false,"recentlyAdded": true,"sourceUrl": "https://www.bizquest.com/businesses-for-sale-in-florida-fl/","scrapedAt": "2026-01-01T00:00:00.000000+00:00","raw": { "header": "Sample Established Service Company", "price": 750000, "urlStub": "sample-established-service-company" }}
Plan Requirement
Residential proxy access is required. BizQuest's edge answers datacenter connections (and requests with no proxy) with an "Access Denied" refusal, so the default connection is Residential, country US, and you need an Apify plan that includes Residential proxy access (or your own residential proxy URLs). Keep the proxy group on Residential. If the default connection is refused, the actor logs: "The selected connection is unavailable to this run. Apify free plans do not include residential proxies. Continuing on a backup connection; some pages may still be unavailable." and, when the backup connection answers, "Served over the backup connection (the default connection was unavailable)." Pages can still be unavailable on the backup connection.
If no results page can be loaded at all, the run ends as failed (never a silent empty dataset) with one of these messages:
- "The proxy connection was refused for this account, so no page could be read. Your Apify plan does not include proxy access; a paid plan is required: https://apify.com/pricing. If you entered your own proxy URLs, check that their credentials are valid."
- "No results: residential proxies are unavailable on this run (Apify free plans do not include them), and the backup connection could not load the requested BizQuest pages. Upgrade at https://apify.com/pricing or supply your own proxy URLs, then try again."
- "Could not load any results page (the requests failed), so nothing was collected. This is a connection problem, not an empty search. Please try again later."
Each listing request has a 25 second budget, so a stuck connection is abandoned and rotated instead of stalling the run. Listing data is read through BizQuest's own search service, which answers where the search web pages refuse connections; the search web pages are only used as a fallback. Broker profile pages require a maintained session, and seeding it is a one-time operator step: paste a fresh cookie jar into the sessionJarSeed input (or the BIZQUEST_SESSION_JAR environment variable) and the actor stores it, serves the broker pages, and keeps the session fresh for later runs. That path runs only when the run allocates at least 2048 MB of memory (set it in the run options when you paste broker profile URLs). The site refuses broker profile pages intermittently. This refusal comes and goes over the day, and a refused run fails fast with a message that says whether the site or the stored session was at fault. Re-running later often succeeds; if repeated runs keep failing, paste a fresh cookie jar into the sessionJarSeed input (search and individual-listing URLs are unaffected). Detail mode reads listing details through BizQuest's own listing data service; individual listing web pages and franchise brand pages are refused even on residential connections, so franchise brand links are skipped with a warning.
FAQ
How much does it cost?
You pay per listing returned (the dataset-item event), plus the detail-enrichment event once per listing whose extra fields were fetched when includeDetails is on, plus the actor-start event. Listings suppressed as UNCHANGED, or skipped because of resume, are not charged. The Pricing tab shows the current rates. Use Max listings to cap the cost of any run.
Is it legal to scrape BizQuest?
This actor collects only publicly available business-for-sale listing data. You are responsible for how you use it: follow BizQuest's terms and the laws that apply to you, and get legal advice if you plan commercial redistribution. Broker names and phone numbers are contact details the listing itself publishes; handle them accordingly.
Can I get only new or changed listings on a schedule?
Yes. Schedule the actor from the Schedules tab and turn on Incremental mode. Each run then returns only new and updated listings, and unchanged ones are not billed. A quiet run that finds nothing changed still completes normally and simply returns zero rows, it is not an error.
Why did my incremental run return fewer rows than Max listings?
Under incremental mode, Max listings caps how many listings are scanned, not how many are returned. If most of what it scans is unchanged, it can legitimately return far fewer rows than the cap, or zero, on a quiet day.
Why did my run fail instead of returning an empty dataset?
A URL list where no URL is a supported shape, a resumeFromRunId that cannot be resolved to a run or dataset you own, or Incremental mode combined with resumeFromRunId on a search that already has saved state, all stop the run with a clear error message rather than a silent empty result. If the site simply returns no matching listings for your filters, or your connection is not being admitted reliably, the run completes and logs "No listings matched. Widen your filters or check your proxy connection, then try again." A run where not one page could be loaded fails with the connection messages listed under Plan Requirement.
Can I use it with AI agents or MCP?
Yes. Call it from any Apify integration or MCP client, and use the connector field to push results into Notion, Linear or Airtable.
๐ Want more leads data?
Pair this actor with these related scrapers from the same team:
| ๐ BizBuySell Scraper Extract business-for-sale and franchise listings from bizbuysell.com with financials... | ๐ BusinessesForSale.com Scraper Extract businesses and franchises listed for sale on BusinessesForSale.com. Search by... |
| ๐ Crexi Scraper Scrape crexi.com commercial listings: asking price, cap rate, square footage, units, year... | ๐จ LoopNet Scraper Scrape LoopNet commercial listings across the US, including office, retail, industrial... |
| ๐ Google Maps Scraper Extract business data from Google Maps at scale. Get names, addresses, phone numbers... | ๐ Flippa Scraper Scrape Flippa listings with full enrichment, including revenue, profit, valuation... |
๐ Browse all abotapi scrapers
๐ฌ Support
- ๐ Found a bug or a missing field? Open a ticket on the Issues tab. We usually reply within hours.
- ๐ ๏ธ Need another site, extra fields or a private build? Email contact@abotapi.com.
- โญ Enjoying it? A quick review on the actor page helps other users find it.