BBB Scraper | Ratings, Reviews and Complaints avatar

BBB Scraper | Ratings, Reviews and Complaints

Pricing

from $3.40 / 1,000 businesses

Go to Apify Store
BBB Scraper | Ratings, Reviews and Complaints

BBB Scraper | Ratings, Reviews and Complaints

BBB scraper for Better Business Bureau (bbb.org): get each business's BBB rating and the reasons, accreditation, owner, email, phone, website, licenses, newest reviews and complaints by type, from a keyword and city or a link. 10 businesses in 5 seconds, 57 fields each. US and Canada, no login.

Pricing

from $3.40 / 1,000 businesses

Rating

0.0

(0)

Developer

SilentFlow

SilentFlow

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

4 days ago

Last modified

Features

Limited permissions

Share

BBB Scraper (Better Business Bureau) | Ratings, Reviews, Complaints and Contacts (2026)

BBB businesses, 57 fields each, from any search.

From SilentFlow. Creators of Facebook Search Scraper and JD Products Scraper (#1 for β€œjd scraper” in Apify Store search), with 920,000+ combined lifetime runs.

Turn any BBB search into a list of businesses you can trust or avoid: letter grade and why, accreditation, owner, email, phone, website, newest reviews and complaints. 10 Denver plumbers in 4 seconds.

Why choose this actor?

Opening BBB profiles one tab at a time to check a vendor? Counting complaints by hand to see what customers are unhappy about? Wondering why a contractor has a B and not an A+?

  • Filter by BBB letter grade. Ask for A-rated businesses only to build a list of trusted vendors, or for D and F to build a watch list of risky ones. The F filter on the Phoenix roofing contractors category returned 15 F-rated businesses in 7 seconds, and nothing else.
  • See why BBB gave the grade. Each row carries BBB's own reasons for the rating. All 15 F-rated Phoenix roofers came with theirs, such as "Failure to have a required competency license", and 4 of the 10 Denver plumbers of the default run had one too.
  • Complaints broken down by type for the whole file. Each row counts the business's complaints per type (Service or Repair Issues, Billing Issues, Order Issues...) over everything BBB has on file, not only the few you read. 6 of the 10 Denver plumbers came with that breakdown, for example 25 service or repair, 5 order and 4 sales and advertising complaints for one of them.

Try BBB Scraper free

Try your first business

Paste this into the JSON tab of the input and press Start. It is the prefilled input: plumbers around Denver, Colorado, capped at 10 businesses.

{
"searchTerms": ["plumber"],
"locations": ["Denver, CO"],
"maxItems": 10
}

You can run it on the Apify Free plan. On November 6, 2026 this input returned 10 businesses in 4 seconds, out of the 1,945 plumbers BBB lists around Denver. All 10 came with their BBB rating, owner name, phone, licenses and complaint counts by status; 9 with a website, 8 with an email address, 9 with social media links. They carried 42 customer reviews and 28 complaints between them. Each business is one row of the dataset, ready to export as JSON, CSV or Excel.

How it works

Copy to your AI assistant

Paste this block into Claude, ChatGPT or Cursor to give it full context about this scraper:

You have access to the BBB Scraper on Apify: silentflow/bbb-scraper
It reads the Better Business Bureau (bbb.org, US and Canada) and returns one row per business,
with its newest reviews and complaints attached.
Input (all optional, give at least one search term or one link):
- searchTerms (array of strings): what you would type in the BBB search box, e.g. ["plumber", "Comcast"]
- locations (array of strings): "City, ST" or ZIP / postal code, e.g. ["Denver, CO", "Toronto, ON", "80212"];
Canada is detected from the province or postal code, "Canada" alone searches all of Canada; empty = all of the US
- startUrls (array of {url}): bbb.org profile, search or category links
- maxItems (integer, default 100): businesses saved across all inputs
- sort (string, default "relevance"): relevance | rating | distance | name | name_desc
- ratings (array): BBB letter grades to keep, any of "A", "B", "C", "D", "F"
- accreditedOnly (boolean, default false): BBB Accredited Businesses only
- distance (integer, miles): 5, 10, 25, 50 or 100 around each location; other values go up to the next one
- maxReviews (integer, default 10): newest reviews attached to each business, 0 to skip
- maxComplaints (integer, default 10): newest complaints attached to each business, 0 keeps only the breakdown
Output per business (64 top-level fields):
- identity: id ("1296-90156205"), url (BBB profile), name, alternateNames[], bbbId, businessId
- business: primaryCategory, categories[], description, productsAndServices, businessType, yearsInBusiness,
businessStarted, incorporated (RFC 3339), numberOfEmployees, isOutOfBusiness,
licenses[] {licenseNumber, agency, agencyUrl, expirationDate}, paymentMethods[],
operatingHours {monday..sunday: "08:00-17:00"}, servingAreas[]
- trust: bbbRating ("A+".."F", "NR"), ratingReasons[], isAccredited, accreditedSince, accreditationRevoked,
bbbFileOpened, alerts[] {title, text}, localBbbName, isClaimed
- contact: ownerName, contacts[] {name, title, isPrincipal}, phone, additionalPhones[], email, website,
additionalWebsites[], socialMedia {facebook, instagram, linkedin, ...}
- reputation: reviewsTotal, averageStarRating (1-5), complaintsTotal (3 years), closedComplaintsLast3Years,
closedComplaintsLast12Months, resolvedComplaints, answeredComplaints, unansweredComplaints,
complaintTypes[] {type, count},
reviews[] {id, rating, author, text, date, businessResponseText, businessResponseDate, customerResponseText, customerResponseDate},
complaints[] {id, type, status, date, text, responses[] {from: business|consumer, text, date}}
- place: addressLine1, addressLine2, city, stateCode, zipCode, countryCode (US|CA), formattedAddress, latitude,
longitude, isHeadquarters
- links and meta: logoUrl, requestQuoteUrl, leaveReviewUrl, searchTerm, searchLocation, scrapedAt (RFC 3339)
Use apify-client for Python or JavaScript: client.actor("silentflow/bbb-scraper").call(run_input=...)

How to scrape BBB ratings, reviews and complaints

Get every plumber BBB lists around Denver

The basic run: one category, one city. Each business comes with its profile, its 10 newest reviews and its 10 newest complaints.

{
"searchTerms": ["plumber"],
"locations": ["Denver, CO"],
"maxItems": 100
}

Build a list of accredited HVAC companies near Dallas and Fort Worth

Two cities in one run, accredited businesses only, within 25 miles of each city. On November 6, 2026 this returned 20 businesses in 9 seconds, 19 of them with a website, carrying 70 reviews and 50 complaints.

{
"searchTerms": ["hvac"],
"locations": ["Dallas, TX", "Fort Worth, TX"],
"accreditedOnly": true,
"distance": 25,
"maxItems": 20
}

Pull the F-rated roofing contractors of Phoenix

Paste the BBB category page you already know and keep only the F grade. BBB listed 64 F-rated businesses for it; the first 15 came back in 7 seconds, each with the reason for its grade, and 13 with a BBB alert about their license.

{
"startUrls": [{ "url": "https://www.bbb.org/us/az/phoenix/category/roofing-contractors" }],
"ratings": ["F"],
"maxItems": 15,
"maxReviews": 3
}

Input parameters

FieldTypeDefaultWhat it does
searchTermsarray of stringsprefilled ["plumber"]What you would type in the BBB search box: a category (roofing, auto repair) or a company name (Comcast). Each term is searched in every location.
locationsarray of stringsprefilled ["Denver, CO"]US or Canadian places as City, ST or a ZIP / postal code. Empty searches all of the US; Canada alone searches all of Canada.
startUrlsarray of linksnonebbb.org profile, search or category pages. A profile link is always read, whatever the filters.
maxItemsinteger100The most businesses saved across all searches and links. Each business is saved once.
sortselectrelevancerelevance, rating, distance, name (A to Z) or name_desc (Z to A).
ratingsmulti-selectevery gradeBBB letter grades to keep: A (A+, A, A-), B, C, D, F.
accreditedOnlybooleanfalseKeep only BBB Accredited Businesses.
distanceinteger (miles)BBB's own area5, 10, 25, 50 or 100 miles around each location. Another value goes up to the next one.
maxReviewsinteger10Newest customer reviews attached to each business. 0 skips them.
maxComplaintsinteger10Newest complaints attached to each business. 0 keeps only the complaint counts and breakdown.

Accepted locations

  • City, ST: Denver, CO, Austin, TX, Toronto, ON, Vancouver, BC. A full state name works too: Denver, Colorado is read as Denver, CO.
  • ZIP or postal code: 80212, M5V 2T6.
  • A whole country: Canada, or leave the field empty for the whole US.
  • A city without its state is read the way BBB reads it, which may be a namesake in another state: Denver alone returned plumbers in North Carolina. Add the state code.
  • Business profile, any tab: https://www.bbb.org/us/co/denver/profile/plumber/ennis-plumbing-llc-1296-90156205, its /customer-reviews, /complaints or /addressId/... pages.
  • Search: https://www.bbb.org/search?find_country=USA&find_text=roofing&find_loc=Phoenix%2C%20AZ. Its own sort and filters are kept; the form fills in the ones the link does not set.
  • Category: https://www.bbb.org/us/az/phoenix/category/roofing-contractors, and the nationwide https://www.bbb.org/near-me/auto-repair pages.

What data can you extract from BBB?

One row is one business as BBB shows it, in 64 top-level fields grouped the way you read a profile:

GroupFields
Identityid, url, name, alternateNames, bbbId, businessId
BusinessprimaryCategory, categories, description, productsAndServices, businessType, yearsInBusiness, businessStarted, incorporated, numberOfEmployees, isOutOfBusiness, licenses, paymentMethods, operatingHours, servingAreas
BBB trustbbbRating, ratingReasons, isAccredited, accreditedSince, accreditationRevoked, bbbFileOpened, alerts, localBbbName, isClaimed
ContactsownerName, contacts, phone, additionalPhones, email, website, additionalWebsites, socialMedia
ReputationreviewsTotal, averageStarRating, complaintsTotal, closedComplaintsLast3Years, closedComplaintsLast12Months, resolvedComplaints, answeredComplaints, unansweredComplaints, complaintTypes, reviews, complaints
PlaceaddressLine1, addressLine2, city, stateCode, zipCode, countryCode, formattedAddress, latitude, longitude, isHeadquarters
Links and metalogoUrl, requestQuoteUrl, leaveReviewUrl, searchTerm, searchLocation, scrapedAt

Nested objects carry their own fields: each review has 9 (rating, author, text, date, the business's reply and the customer's answer with their dates), each complaint 6 (type, status, date, text and the thread of replies, each reply with who wrote it, its text and its date), each license 4 (number, agency, agency site, expiry date).

Good to know about the data:

  • id and url are stable: id is BBB's own file number (1296-90156205) and url the permanent profile page.
  • Dates are RFC 3339 in UTC (2013-05-06T00:00:00Z).
  • email is the address BBB publishes for the business, readable as is. Not every business lists one: 8 of the 10 Denver plumbers did.
  • complaintsTotal is BBB's count for the last 3 years. resolvedComplaints, answeredComplaints, unansweredComplaints and complaintTypes count the whole file BBB keeps, so they can be higher.
  • A branch found near your location comes back as its local BBB report (local address, phone and rating). Its reviews and complaints are those BBB files under the head office, the way bbb.org shows them.
  • BBB masks some words in review and complaint texts with asterisks; the texts are returned exactly as BBB shows them.
  • logoUrl points to BBB's image server and stays valid as long as the business keeps its logo on BBB.

Output example

A real row from the default run of November 6, 2026. Long texts and lists are shortened here; the dataset has them in full.

{
"id": "1296-1000194172",
"url": "https://www.bbb.org/us/co/denver/profile/plumber/heart-heating-cooling-plumbing-electric-1296-1000194172",
"name": "Heart Heating, Cooling, Plumbing & Electric",
"alternateNames": ["Heart HCPE Group, LLC"],
"bbbId": "1296",
"businessId": "1000194172",
"primaryCategory": "Plumber",
"categories": ["Plumber", "Air Conditioning Contractors", "Electrical Contractors", "Furnace Repair", "Drain Cleaning"],
"description": "Heart Heating, Cooling, Plumbing & Electric is your go-to for comprehensive home services in metro Denver and across the Front Range...",
"productsAndServices": null,
"businessType": "Limited Liability Company (LLC)",
"yearsInBusiness": 2,
"businessStarted": "2024-10-14T00:00:00Z",
"incorporated": "2024-10-14T00:00:00Z",
"numberOfEmployees": null,
"isOutOfBusiness": false,
"licenses": [
{
"licenseNumber": "PC.0004176",
"agency": "Department of Regulatory Agencies (DORA)",
"agencyUrl": "https://dpo.colorado.gov/",
"expirationDate": "2027-02-28T00:00:00Z"
}
],
"paymentMethods": null,
"operatingHours": {
"monday": "07:00-18:00",
"tuesday": "07:00-18:00",
"wednesday": "07:00-18:00",
"thursday": "07:00-18:00",
"friday": "07:00-18:00",
"saturday": "07:00-18:00",
"sunday": "07:00-18:00"
},
"servingAreas": ["Agate, CO", "Arvada, CO", "Aurora, CO", "Denver, CO", "Westminster, CO"],
"bbbRating": "A",
"ratingReasons": ["Length of time business has been operating"],
"isAccredited": true,
"accreditedSince": "2026-03-23T00:00:00Z",
"accreditationRevoked": null,
"bbbFileOpened": "2026-03-05T00:00:00Z",
"alerts": null,
"localBbbName": "BBB Great West + Pacific",
"isClaimed": true,
"ownerName": "Mr. Josh Friedman",
"contacts": [
{ "name": "Mr. Josh Friedman", "title": "Owner", "isPrincipal": true },
{ "name": "Mr. Josh Charlton", "title": "CEO", "isPrincipal": false }
],
"phone": "(720) 340-3502",
"additionalPhones": ["(720) 712-0394"],
"email": "customerservice@heart-hvac.com",
"website": "https://www.servicebyheart.com",
"additionalWebsites": ["https://www.tiktok.com/@hearthvac", "https://x.com/heart_heating"],
"socialMedia": {
"facebook": "https://www.facebook.com/heartheatingcooling/",
"instagram": "https://www.instagram.com/heartheatingcooling/"
},
"reviewsTotal": 14,
"averageStarRating": 4.07,
"complaintsTotal": 4,
"closedComplaintsLast3Years": 4,
"closedComplaintsLast12Months": 2,
"resolvedComplaints": 0,
"answeredComplaints": 4,
"unansweredComplaints": 0,
"complaintTypes": [{ "type": "Service or Repair Issues", "count": 4 }],
"reviews": [
{
"id": "1296_1000194172_846024",
"rating": 1,
"author": "Anthony S",
"text": "Hearts plumbing: I had a very disappointing experience with Hearts Plumbing. After receiving a quote, I simply asked for a moment to consult my wife regarding our budget...",
"date": "2026-01-25T00:00:00Z",
"businessResponseText": null,
"businessResponseDate": null,
"customerResponseText": null,
"customerResponseDate": null
}
],
"complaints": [
{
"id": "1296_1000194172_24769865",
"type": "Service or Repair Issues",
"status": "Answered",
"date": "2026-04-21T00:00:00Z",
"text": "Hired Heart Plumbing and Heating LLC, to install a new HVAC system in our home approx 2 years ago. Several months after installation, I found the humidifier system was improperly installed...",
"responses": [
{
"from": "consumer",
"text": "For clarification, and after checking dates, etc: July 2024: We bought a new HVAC system from Heart...",
"date": "2026-04-29T00:00:00Z"
},
{
"from": "business",
"text": "To Whom It May Concern: Thank you for the opportunity to respond. We have reviewed the customer's concerns carefully...",
"date": "2026-05-28T00:00:00Z"
}
]
}
],
"addressLine1": "646 Bryant Street",
"addressLine2": null,
"city": "Denver",
"stateCode": "CO",
"zipCode": "80204",
"countryCode": "US",
"formattedAddress": "646 Bryant Street, Denver, CO 80204",
"latitude": 39.726715,
"longitude": -105.018379,
"isHeadquarters": false,
"logoUrl": "https://m.bbb.org/prod/ProfileImages/2026/b6cebf38-32a3-4cbd-a2c0-4359167cb5d7.png",
"requestQuoteUrl": "https://www.bbb.org/greatwestpacific/quote/request-heart-heating-cooling-plumbing-electric-1000194172",
"leaveReviewUrl": "https://www.bbb.org/us/co/denver/profile/plumber/heart-heating-cooling-plumbing-electric-1296-1000194172/leave-a-review",
"searchTerm": "plumber",
"searchLocation": "Denver, CO",
"scrapedAt": "2026-11-06T16:31:18Z"
}

Advanced usage

Build a lead list of trusted contractors across a metro area

Several cities, A grades only, accredited only. Each business is saved once even when two cities find it, and searchLocation tells you which city brought it in.

{
"searchTerms": ["roofing", "remodeling"],
"locations": ["Phoenix, AZ", "Scottsdale, AZ", "Mesa, AZ"],
"ratings": ["A"],
"accreditedOnly": true,
"maxItems": 300,
"maxReviews": 0
}

Set maxReviews to 0 when you only need contacts: each business then needs one less page and the run is faster.

Keep a watch list of risky businesses in your category

D and F grades, worst first. Pair ratingReasons, alerts and unansweredComplaints to see at a glance who lost their license, who ignores complaints and who simply has not been rated long enough.

{
"searchTerms": ["auto repair"],
"locations": ["Houston, TX"],
"ratings": ["D", "F"],
"sort": "rating",
"maxItems": 100,
"maxComplaints": 5
}

Follow the complaints of one company every week

Paste the profile and raise the complaint cap. Schedule the run weekly on Apify and compare complaintTypes and unansweredComplaints from one week to the next; the newest complaints come first.

{
"startUrls": [{ "url": "https://www.bbb.org/us/pa/philadelphia/profile/internet-providers/comcast-corporation-0241-80003221" }],
"maxReviews": 50,
"maxComplaints": 100
}

Search all of Canada for one trade

Canada alone searches every province. A city with its province (Toronto, ON) or a postal code (M5V 2T6) narrows it. On November 6, 2026 roofing around Toronto, ON sorted by rating returned 12 businesses in 4 seconds, all of them in the Toronto area.

{
"searchTerms": ["roofing"],
"locations": ["Canada"],
"sort": "rating",
"maxItems": 100
}

Check a list of vendors by name before you sign

Type company names as search terms, one per line, with the city they work in. Keep maxItems close to the number of names so each search returns its best match first.

{
"searchTerms": ["Repipe Specialists", "Heart Heating Cooling Plumbing", "Speed Plumbing Services"],
"locations": ["Denver, CO"],
"sort": "relevance",
"maxItems": 10,
"maxReviews": 5,
"maxComplaints": 5
}

Export the dataset as CSV or Excel from the run page, or read it from the Apify API in JSON for your CRM or risk tool.

FAQ

What is BBB? The Better Business Bureau is a non-profit network that keeps a public file on millions of businesses in the US and Canada. Each file carries a letter grade from A+ to F, the BBB accreditation status, customer reviews and the complaints customers filed through BBB, with the business's answers.

What does one row contain? One business: its identity and categories, its BBB rating with the reasons BBB gives, its accreditation, owner and contacts (phone, email, website, social media), licenses, opening hours, address with coordinates, review and complaint counts, the complaint breakdown by type and by status, and its newest reviews and complaints with the replies.

Do I need a BBB account? No. The actor reads the public BBB pages anyone can open. No login, no account, no API key.

How fresh is the data? Live. Every run reads BBB at the time it runs, and each row carries scrapedAt. Ratings, reviews and complaints change every week, so schedule the actor if you track them.

How many businesses can one run return? There is no fixed limit on the run: maxItems sets it. BBB itself shows at most 225 businesses per search (15 pages of 15), even when it counts more: 1,945 plumbers around Denver, 2,501 roofers around Toronto. To go further, add locations or search terms; each business is saved once across all of them.

Does it work in Canada? Yes. Type a Canadian city with its province (Toronto, ON), a postal code (M5V 2T6) or Canada, or paste a bbb.org/ca/... link. Canadian rows have countryCode: "CA".

Do the filters combine? Yes. ratings, accreditedOnly, distance and sort apply together to every search term and every search or category link. For example ratings: ["A"] with accreditedOnly: true and distance: 10 returns accredited A-rated businesses within 10 miles of each location. A profile link is always read, whatever the filters.

Why do some rows have no email or website? Because BBB has none on file for that business. The default run found an email for 8 of 10 Denver plumbers and a website for 9 of 10. F-rated businesses list fewer: 3 emails for 15 F-rated Phoenix roofers, as many of them no longer trade.

What is the difference between complaintsTotal and complaintTypes? complaintsTotal is BBB's count of complaints over the last 3 years, the number shown on the profile. complaintTypes, resolvedComplaints, answeredComplaints and unansweredComplaints count every complaint BBB keeps in the file, by type and by status, so they can be higher. All of them are filled even when you set maxComplaints to 0.

Are all reviews and complaints of a business returned? The newest ones, up to maxReviews and maxComplaints per business (10 each by default, up to 1,000). Large companies have thousands; raise the caps for more. A branch shows the reviews and complaints BBB files under its head office, the same ones bbb.org shows.

Which links stay valid? url is the permanent BBB profile and id never changes for a business. requestQuoteUrl and leaveReviewUrl open BBB's own forms for that business. website and socialMedia are the business's own links as BBB lists them.

More SilentFlow scrapers

πŸ›’ E-commerce

πŸ’Ό Jobs

🏠 Real estate

πŸ“£ Social media

🏒 Business data

✈️ Travel

🎯 Lead generation

πŸ”Ž SEO

🎬 Video

πŸ“° News

🧰 More tools

Support

Need something this scraper doesn't do yet? We ship features fast.

  • Feature requests go straight to our backlog
  • Enterprise needs? We do custom integrations and high-volume plans
  • Pricing questions? Check the Monetization tab on the actor page

Response time: usually under 24 hours.

This Actor extracts publicly available business data from bbb.org. It does not bypass any login, paywall or CAPTCHA. Users are responsible for complying with BBB's terms of service and with the data protection laws that apply to them (GDPR, CCPA, and PIPL where relevant). Rows contain personal data: the names and titles of owners and contacts, business email addresses and phone numbers, and the display names reviewers chose; complaint and review texts are returned as BBB publishes them, with the words BBB masked. Handle that data accordingly, for example when you contact the businesses. The data is informational; verify it before any regulated decision such as credit or insurance.

Built by SilentFlow for teams that qualify vendors, build local lead lists and watch reputations, one BBB business per row, across the US and Canada.